mirror of
				https://github.com/SoPat712/YTLitePlus.git
				synced 2025-10-31 12:54:14 -04:00 
			
		
		
		
	added files via upload
This commit is contained in:
		
							
								
								
									
										15
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXCarouselCell.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXCarouselCell.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| // | ||||
| //  FLEXCarouselCell.h | ||||
| //  FLEX | ||||
| // | ||||
| //  Created by Tanner Bennett on 7/17/19. | ||||
| //  Copyright © 2020 FLEX Team. All rights reserved. | ||||
| // | ||||
|  | ||||
| #import <UIKit/UIKit.h> | ||||
|  | ||||
| @interface FLEXCarouselCell : UICollectionViewCell | ||||
|  | ||||
| @property (nonatomic, copy) NSString *title; | ||||
|  | ||||
| @end | ||||
							
								
								
									
										93
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXCarouselCell.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXCarouselCell.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| // | ||||
| //  FLEXCarouselCell.m | ||||
| //  FLEX | ||||
| // | ||||
| //  Created by Tanner Bennett on 7/17/19. | ||||
| //  Copyright © 2020 FLEX Team. All rights reserved. | ||||
| // | ||||
|  | ||||
| #import "FLEXCarouselCell.h" | ||||
| #import "FLEXColor.h" | ||||
| #import "UIView+FLEX_Layout.h" | ||||
|  | ||||
| @interface FLEXCarouselCell () | ||||
| @property (nonatomic, readonly) UILabel *titleLabel; | ||||
| @property (nonatomic, readonly) UIView *selectionIndicatorStripe; | ||||
| @property (nonatomic) BOOL constraintsInstalled; | ||||
| @end | ||||
|  | ||||
| @implementation FLEXCarouselCell | ||||
|  | ||||
| - (instancetype)initWithFrame:(CGRect)frame { | ||||
|     self = [super initWithFrame:frame]; | ||||
|     if (self) { | ||||
|         _titleLabel = [UILabel new]; | ||||
|         _selectionIndicatorStripe = [UIView new]; | ||||
|  | ||||
|         self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; | ||||
|         self.selectionIndicatorStripe.backgroundColor = self.tintColor; | ||||
|         if (@available(iOS 10, *)) { | ||||
|             self.titleLabel.adjustsFontForContentSizeCategory = YES; | ||||
|         } | ||||
|  | ||||
|         [self.contentView addSubview:self.titleLabel]; | ||||
|         [self.contentView addSubview:self.selectionIndicatorStripe]; | ||||
|  | ||||
|         [self installConstraints]; | ||||
|  | ||||
|         [self updateAppearance]; | ||||
|     } | ||||
|  | ||||
|     return self; | ||||
| } | ||||
|  | ||||
| - (void)updateAppearance { | ||||
|     self.selectionIndicatorStripe.hidden = !self.selected; | ||||
|  | ||||
|     if (self.selected) { | ||||
|         self.titleLabel.textColor = self.tintColor; | ||||
|     } else { | ||||
|         self.titleLabel.textColor = FLEXColor.deemphasizedTextColor; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #pragma mark Public | ||||
|  | ||||
| - (NSString *)title { | ||||
|     return self.titleLabel.text; | ||||
| } | ||||
|  | ||||
| - (void)setTitle:(NSString *)title { | ||||
|     self.titleLabel.text = title; | ||||
|     [self.titleLabel sizeToFit]; | ||||
|     [self setNeedsLayout]; | ||||
| } | ||||
|  | ||||
| #pragma mark Overrides | ||||
|  | ||||
| - (void)prepareForReuse { | ||||
|     [super prepareForReuse]; | ||||
|     [self updateAppearance]; | ||||
| } | ||||
|  | ||||
| - (void)installConstraints { | ||||
|     CGFloat stripeHeight = 2; | ||||
|  | ||||
|     self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO; | ||||
|     self.selectionIndicatorStripe.translatesAutoresizingMaskIntoConstraints = NO; | ||||
|  | ||||
|     UIView *superview = self.contentView; | ||||
|     [self.titleLabel flex_pinEdgesToSuperviewWithInsets:UIEdgeInsetsMake(10, 15, 8 + stripeHeight, 15)]; | ||||
|  | ||||
|     [self.selectionIndicatorStripe.leadingAnchor constraintEqualToAnchor:superview.leadingAnchor].active = YES; | ||||
|     [self.selectionIndicatorStripe.bottomAnchor constraintEqualToAnchor:superview.bottomAnchor].active = YES; | ||||
|     [self.selectionIndicatorStripe.trailingAnchor constraintEqualToAnchor:superview.trailingAnchor].active = YES; | ||||
|     [self.selectionIndicatorStripe.heightAnchor constraintEqualToConstant:stripeHeight].active = YES; | ||||
| } | ||||
|  | ||||
| - (void)setSelected:(BOOL)selected { | ||||
|     super.selected = selected; | ||||
|     [self updateAppearance]; | ||||
| } | ||||
|  | ||||
| @end | ||||
							
								
								
									
										20
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXScopeCarousel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXScopeCarousel.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| // | ||||
| //  FLEXScopeCarousel.h | ||||
| //  FLEX | ||||
| // | ||||
| //  Created by Tanner Bennett on 7/17/19. | ||||
| //  Copyright © 2020 FLEX Team. All rights reserved. | ||||
| // | ||||
|  | ||||
| #import <UIKit/UIKit.h> | ||||
|  | ||||
| /// Only use on iOS 10 and up. Requires iOS 10 APIs for calculating row sizes. | ||||
| @interface FLEXScopeCarousel : UIControl | ||||
|  | ||||
| @property (nonatomic, copy) NSArray<NSString *> *items; | ||||
| @property (nonatomic) NSInteger selectedIndex; | ||||
| @property (nonatomic) void(^selectedIndexChangedAction)(NSInteger idx); | ||||
|  | ||||
| - (void)registerBlockForDynamicTypeChanges:(void(^)(FLEXScopeCarousel *))handler; | ||||
|  | ||||
| @end | ||||
							
								
								
									
										204
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXScopeCarousel.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								Tweaks/FLEX/Core/Views/Carousel/FLEXScopeCarousel.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,204 @@ | ||||
| // | ||||
| //  FLEXScopeCarousel.m | ||||
| //  FLEX | ||||
| // | ||||
| //  Created by Tanner Bennett on 7/17/19. | ||||
| //  Copyright © 2020 FLEX Team. All rights reserved. | ||||
| // | ||||
|  | ||||
| #import "FLEXScopeCarousel.h" | ||||
| #import "FLEXCarouselCell.h" | ||||
| #import "FLEXColor.h" | ||||
| #import "FLEXMacros.h" | ||||
| #import "UIView+FLEX_Layout.h" | ||||
|  | ||||
| const CGFloat kCarouselItemSpacing = 0; | ||||
| NSString * const kCarouselCellReuseIdentifier = @"kCarouselCellReuseIdentifier"; | ||||
|  | ||||
| @interface FLEXScopeCarousel () <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> | ||||
| @property (nonatomic, readonly) UICollectionView *collectionView; | ||||
| @property (nonatomic, readonly) FLEXCarouselCell *sizingCell; | ||||
|  | ||||
| @property (nonatomic, readonly) id dynamicTypeObserver; | ||||
| @property (nonatomic, readonly) NSMutableArray *dynamicTypeHandlers; | ||||
|  | ||||
| @property (nonatomic) BOOL constraintsInstalled; | ||||
| @end | ||||
|  | ||||
| @implementation FLEXScopeCarousel | ||||
|  | ||||
| - (id)initWithFrame:(CGRect)frame { | ||||
|     self = [super initWithFrame:frame]; | ||||
|     if (self) { | ||||
|         self.backgroundColor = FLEXColor.primaryBackgroundColor; | ||||
|         self.autoresizingMask = UIViewAutoresizingFlexibleWidth; | ||||
|         self.translatesAutoresizingMaskIntoConstraints = YES; | ||||
|         _dynamicTypeHandlers = [NSMutableArray new]; | ||||
|          | ||||
|         CGSize itemSize = CGSizeZero; | ||||
|         if (@available(iOS 10.0, *)) { | ||||
|             itemSize = UICollectionViewFlowLayoutAutomaticSize; | ||||
|         } | ||||
|  | ||||
|         // Collection view layout | ||||
|         UICollectionViewFlowLayout *layout = ({ | ||||
|             UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new]; | ||||
|             layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; | ||||
|             layout.sectionInset = UIEdgeInsetsZero; | ||||
|             layout.minimumLineSpacing = kCarouselItemSpacing; | ||||
|             layout.itemSize = itemSize; | ||||
|             layout.estimatedItemSize = itemSize; | ||||
|             layout; | ||||
|         }); | ||||
|  | ||||
|         // Collection view | ||||
|         _collectionView = ({ | ||||
|             UICollectionView *cv = [[UICollectionView alloc] | ||||
|                 initWithFrame:CGRectZero | ||||
|                 collectionViewLayout:layout | ||||
|             ]; | ||||
|             cv.showsHorizontalScrollIndicator = NO; | ||||
|             cv.backgroundColor = UIColor.clearColor; | ||||
|             cv.delegate = self; | ||||
|             cv.dataSource = self; | ||||
|             [cv registerClass:[FLEXCarouselCell class] forCellWithReuseIdentifier:kCarouselCellReuseIdentifier]; | ||||
|  | ||||
|             [self addSubview:cv]; | ||||
|             cv; | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         // Sizing cell | ||||
|         _sizingCell = [FLEXCarouselCell new]; | ||||
|         self.sizingCell.title = @"NSObject"; | ||||
|  | ||||
|         // Dynamic type | ||||
|         weakify(self); | ||||
|         _dynamicTypeObserver = [NSNotificationCenter.defaultCenter | ||||
|             addObserverForName:UIContentSizeCategoryDidChangeNotification | ||||
|             object:nil queue:nil usingBlock:^(NSNotification *note) { strongify(self) | ||||
|                 [self.collectionView setNeedsLayout]; | ||||
|                 [self setNeedsUpdateConstraints]; | ||||
|  | ||||
|                 // Notify observers | ||||
|                 for (void (^block)(FLEXScopeCarousel *) in self.dynamicTypeHandlers) { | ||||
|                     block(self); | ||||
|                 } | ||||
|             } | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     return self; | ||||
| } | ||||
|  | ||||
| - (void)dealloc { | ||||
|     [NSNotificationCenter.defaultCenter removeObserver:self.dynamicTypeObserver]; | ||||
| } | ||||
|  | ||||
| #pragma mark - Overrides | ||||
|  | ||||
| - (void)drawRect:(CGRect)rect { | ||||
|     [super drawRect:rect]; | ||||
|  | ||||
|     CGFloat width = 1.f / UIScreen.mainScreen.scale; | ||||
|  | ||||
|     // Draw hairline | ||||
|     CGContextRef context = UIGraphicsGetCurrentContext(); | ||||
|     CGContextSetStrokeColorWithColor(context, FLEXColor.hairlineColor.CGColor); | ||||
|     CGContextSetLineWidth(context, width); | ||||
|     CGContextMoveToPoint(context, 0, rect.size.height - width); | ||||
|     CGContextAddLineToPoint(context, rect.size.width, rect.size.height - width); | ||||
|     CGContextStrokePath(context); | ||||
| } | ||||
|  | ||||
| + (BOOL)requiresConstraintBasedLayout { | ||||
|     return YES; | ||||
| } | ||||
|  | ||||
| - (void)updateConstraints { | ||||
|     if (!self.constraintsInstalled) { | ||||
|         self.collectionView.translatesAutoresizingMaskIntoConstraints = NO; | ||||
|         [self.collectionView flex_pinEdgesToSuperview]; | ||||
|          | ||||
|         self.constraintsInstalled = YES; | ||||
|     } | ||||
|      | ||||
|     [super updateConstraints]; | ||||
| } | ||||
|  | ||||
| - (CGSize)intrinsicContentSize { | ||||
|     return CGSizeMake( | ||||
|         UIViewNoIntrinsicMetric, | ||||
|         [self.sizingCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height | ||||
|     ); | ||||
| } | ||||
|  | ||||
| #pragma mark - Public | ||||
|  | ||||
| - (void)setItems:(NSArray<NSString *> *)items { | ||||
|     NSParameterAssert(items.count); | ||||
|  | ||||
|     _items = items.copy; | ||||
|  | ||||
|     // Refresh list, select first item initially | ||||
|     [self.collectionView reloadData]; | ||||
|     self.selectedIndex = 0; | ||||
| } | ||||
|  | ||||
| - (void)setSelectedIndex:(NSInteger)idx { | ||||
|     NSParameterAssert(idx < self.items.count); | ||||
|  | ||||
|     _selectedIndex = idx; | ||||
|     NSIndexPath *path = [NSIndexPath indexPathForItem:idx inSection:0]; | ||||
|     [self.collectionView selectItemAtIndexPath:path | ||||
|                                       animated:YES | ||||
|                                 scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; | ||||
|     [self collectionView:self.collectionView didSelectItemAtIndexPath:path]; | ||||
| } | ||||
|  | ||||
| - (void)registerBlockForDynamicTypeChanges:(void (^)(FLEXScopeCarousel *))handler { | ||||
|     [self.dynamicTypeHandlers addObject:handler]; | ||||
| } | ||||
|  | ||||
| #pragma mark - UICollectionView | ||||
|  | ||||
| - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { | ||||
| //    if (@available(iOS 10.0, *)) { | ||||
| //        return UICollectionViewFlowLayoutAutomaticSize; | ||||
| //    } | ||||
|      | ||||
|     self.sizingCell.title = self.items[indexPath.item]; | ||||
|     return [self.sizingCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; | ||||
| } | ||||
|  | ||||
| - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { | ||||
|     return self.items.count; | ||||
| } | ||||
|  | ||||
| - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView | ||||
|                   cellForItemAtIndexPath:(NSIndexPath *)indexPath { | ||||
|     FLEXCarouselCell *cell = (id)[collectionView dequeueReusableCellWithReuseIdentifier:kCarouselCellReuseIdentifier | ||||
|                                                                            forIndexPath:indexPath]; | ||||
|     cell.title = self.items[indexPath.row]; | ||||
|     return cell; | ||||
| } | ||||
|  | ||||
| - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { | ||||
|     _selectedIndex = indexPath.item; // In case self.selectedIndex didn't trigger this call | ||||
|  | ||||
|     if (self.selectedIndexChangedAction) { | ||||
|         self.selectedIndexChangedAction(indexPath.row); | ||||
|     } | ||||
|  | ||||
|     // TODO: dynamically choose a scroll position. Very wide items should | ||||
|     // get "Left" while smaller items should not scroll at all, unless | ||||
|     // they are only partially on the screen, in which case they | ||||
|     // should get "HorizontallyCentered" to bring them onto the screen. | ||||
|     // For now, everything goes to the left, as this has a similar effect. | ||||
|     [collectionView scrollToItemAtIndexPath:indexPath | ||||
|                            atScrollPosition:UICollectionViewScrollPositionLeft | ||||
|                                    animated:YES]; | ||||
|     [self sendActionsForControlEvents:UIControlEventValueChanged]; | ||||
| } | ||||
|  | ||||
| @end | ||||
		Reference in New Issue
	
	Block a user
	 Balackburn
					Balackburn