New file |
| | |
| | | // |
| | | // CYLTabBarController.m |
| | | // CYLTabBarController |
| | | // |
| | | // v1.16.0 Created by 微博@iOS程序犭袁 ( http://weibo.com/luohanchenyilong/ ) on 10/20/15. |
| | | // Copyright © 2015 https://github.com/ChenYilong . All rights reserved. |
| | | // |
| | | |
| | | #import "CYLTabBarController.h" |
| | | #import "CYLTabBar.h" |
| | | #import <objc/runtime.h> |
| | | #import "UIViewController+CYLTabBarControllerExtention.h" |
| | | |
| | | NSString *const CYLTabBarItemTitle = @"CYLTabBarItemTitle"; |
| | | NSString *const CYLTabBarItemImage = @"CYLTabBarItemImage"; |
| | | NSString *const CYLTabBarItemSelectedImage = @"CYLTabBarItemSelectedImage"; |
| | | NSString *const CYLTabBarItemImageInsets = @"CYLTabBarItemImageInsets"; |
| | | NSString *const CYLTabBarItemTitlePositionAdjustment = @"CYLTabBarItemTitlePositionAdjustment"; |
| | | |
| | | NSUInteger CYLTabbarItemsCount = 0; |
| | | NSUInteger CYLPlusButtonIndex = 0; |
| | | CGFloat CYLTabBarItemWidth = 0.0f; |
| | | NSString *const CYLTabBarItemWidthDidChangeNotification = @"CYLTabBarItemWidthDidChangeNotification"; |
| | | static void * const CYLTabImageViewDefaultOffsetContext = (void*)&CYLTabImageViewDefaultOffsetContext; |
| | | |
| | | @interface CYLTabBarController () <UITabBarControllerDelegate> |
| | | |
| | | @property (nonatomic, assign, getter=isObservingTabImageViewDefaultOffset) BOOL observingTabImageViewDefaultOffset; |
| | | |
| | | @end |
| | | @implementation CYLTabBarController |
| | | |
| | | @synthesize viewControllers = _viewControllers; |
| | | |
| | | #pragma mark - |
| | | #pragma mark - Life Cycle |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | if (CYL_IS_IPHONE_X) { |
| | | self.tabBarHeight = 83; |
| | | } |
| | | // 处理tabBar,使用自定义 tabBar 添加 发布按钮 |
| | | [self setUpTabBar]; |
| | | // KVO注册监听 |
| | | if (!self.isObservingTabImageViewDefaultOffset) { |
| | | [self.tabBar addObserver:self forKeyPath:@"tabImageViewDefaultOffset" options:NSKeyValueObservingOptionNew context:CYLTabImageViewDefaultOffsetContext]; |
| | | self.observingTabImageViewDefaultOffset = YES; |
| | | } |
| | | } |
| | | |
| | | - (void)setViewDidLayoutSubViewsBlock:(CYLViewDidLayoutSubViewsBlock)viewDidLayoutSubviewsBlock { |
| | | _viewDidLayoutSubviewsBlock = viewDidLayoutSubviewsBlock; |
| | | } |
| | | |
| | | - (void)viewDidLayoutSubviews { |
| | | CGFloat deviceVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; |
| | | if (deviceVersion >= 10 && deviceVersion < 10.2) { |
| | | [self.tabBar layoutSubviews];//Fix issue #93 |
| | | } |
| | | UITabBar *tabBar = self.tabBar; |
| | | for (UIControl *control in tabBar.subviews) { |
| | | if ([control isKindOfClass:[UIControl class]]) { |
| | | SEL actin = @selector(didSelectControl:); |
| | | [control addTarget:self action:actin forControlEvents:UIControlEventTouchUpInside]; |
| | | } |
| | | } |
| | | !self.viewDidLayoutSubviewsBlock ?: self.viewDidLayoutSubviewsBlock(self); |
| | | } |
| | | |
| | | - (void)viewWillLayoutSubviews { |
| | | if (!(self.tabBarHeight > 0)) { |
| | | return; |
| | | } |
| | | self.tabBar.frame = ({ |
| | | CGRect frame = self.tabBar.frame; |
| | | CGFloat tabBarHeight = self.tabBarHeight; |
| | | frame.size.height = tabBarHeight; |
| | | frame.origin.y = self.view.frame.size.height - tabBarHeight; |
| | | frame; |
| | | }); |
| | | } |
| | | |
| | | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { |
| | | UIViewController *controller = self.selectedViewController; |
| | | if ([controller isKindOfClass:[UINavigationController class]]) { |
| | | UINavigationController *navigationController = (UINavigationController *)controller; |
| | | return navigationController.topViewController.supportedInterfaceOrientations; |
| | | } else { |
| | | return controller.supportedInterfaceOrientations; |
| | | } |
| | | } |
| | | |
| | | - (void)dealloc { |
| | | UIButton<CYLPlusButtonSubclassing> *plusButton = CYLExternPlusButton; |
| | | if (plusButton.superview && (plusButton.superview == self.tabBar)) { |
| | | plusButton.selected = NO; |
| | | [plusButton removeFromSuperview]; |
| | | } |
| | | BOOL isAdded = [self isPlusViewControllerAdded:_viewControllers]; |
| | | BOOL hasPlusChildViewController = [self hasPlusChildViewController] && isAdded; |
| | | if (isAdded && hasPlusChildViewController && CYLPlusChildViewController.cyl_plusViewControllerEverAdded == YES) { |
| | | [CYLPlusChildViewController cyl_setPlusViewControllerEverAdded:NO]; |
| | | } |
| | | // KVO反注册 |
| | | if (self.isObservingTabImageViewDefaultOffset) { |
| | | [self.tabBar removeObserver:self forKeyPath:@"tabImageViewDefaultOffset"]; |
| | | } |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark - public Methods |
| | | |
| | | - (instancetype)initWithViewControllers:(NSArray<UIViewController *> *)viewControllers tabBarItemsAttributes:(NSArray<NSDictionary *> *)tabBarItemsAttributes { |
| | | return [self initWithViewControllers:viewControllers |
| | | tabBarItemsAttributes:tabBarItemsAttributes |
| | | imageInsets:UIEdgeInsetsZero |
| | | titlePositionAdjustment:UIOffsetZero |
| | | context:nil]; |
| | | } |
| | | |
| | | - (instancetype)initWithViewControllers:(NSArray<UIViewController *> *)viewControllers |
| | | tabBarItemsAttributes:(NSArray<NSDictionary *> *)tabBarItemsAttributes |
| | | imageInsets:(UIEdgeInsets)imageInsets |
| | | titlePositionAdjustment:(UIOffset)titlePositionAdjustment { |
| | | |
| | | return [self initWithViewControllers:viewControllers |
| | | tabBarItemsAttributes:tabBarItemsAttributes |
| | | imageInsets:imageInsets |
| | | titlePositionAdjustment:titlePositionAdjustment |
| | | context:nil]; |
| | | } |
| | | |
| | | - (instancetype)initWithViewControllers:(NSArray<UIViewController *> *)viewControllers |
| | | tabBarItemsAttributes:(NSArray<NSDictionary *> *)tabBarItemsAttributes |
| | | imageInsets:(UIEdgeInsets)imageInsets |
| | | titlePositionAdjustment:(UIOffset)titlePositionAdjustment |
| | | context:(NSString *)context { |
| | | if (self = [super init]) { |
| | | _imageInsets = imageInsets; |
| | | _titlePositionAdjustment = titlePositionAdjustment; |
| | | _tabBarItemsAttributes = tabBarItemsAttributes; |
| | | self.context = context; |
| | | self.viewControllers = viewControllers; |
| | | if ([self hasPlusChildViewController]) { |
| | | self.delegate = self; |
| | | } |
| | | } |
| | | return self; |
| | | } |
| | | |
| | | - (void)setContext:(NSString *)context { |
| | | if (context && context.length > 0) { |
| | | _context = [context copy]; |
| | | } else { |
| | | _context = NSStringFromClass([CYLTabBarController class]); |
| | | } |
| | | [self.tabBar setValue:_context forKey:@"context"]; |
| | | } |
| | | |
| | | + (instancetype)tabBarControllerWithViewControllers:(NSArray<UIViewController *> *)viewControllers |
| | | tabBarItemsAttributes:(NSArray<NSDictionary *> *)tabBarItemsAttributes |
| | | imageInsets:(UIEdgeInsets)imageInsets |
| | | titlePositionAdjustment:(UIOffset)titlePositionAdjustment |
| | | context:(NSString *)context { |
| | | return [[self alloc] initWithViewControllers:viewControllers |
| | | tabBarItemsAttributes:tabBarItemsAttributes |
| | | imageInsets:imageInsets |
| | | titlePositionAdjustment:titlePositionAdjustment |
| | | context:context]; |
| | | } |
| | | |
| | | + (instancetype)tabBarControllerWithViewControllers:(NSArray<UIViewController *> *)viewControllers |
| | | tabBarItemsAttributes:(NSArray<NSDictionary *> *)tabBarItemsAttributes |
| | | imageInsets:(UIEdgeInsets)imageInsets |
| | | titlePositionAdjustment:(UIOffset)titlePositionAdjustment { |
| | | return [[self alloc] initWithViewControllers:viewControllers |
| | | tabBarItemsAttributes:tabBarItemsAttributes |
| | | imageInsets:imageInsets |
| | | titlePositionAdjustment:titlePositionAdjustment |
| | | context:nil]; |
| | | } |
| | | |
| | | + (instancetype)tabBarControllerWithViewControllers:(NSArray<UIViewController *> *)viewControllers tabBarItemsAttributes:(NSArray<NSDictionary *> *)tabBarItemsAttributes { |
| | | return [self tabBarControllerWithViewControllers:viewControllers |
| | | tabBarItemsAttributes:tabBarItemsAttributes |
| | | imageInsets:UIEdgeInsetsZero |
| | | titlePositionAdjustment:UIOffsetZero]; |
| | | } |
| | | |
| | | - (void)hideTabBadgeBackgroundSeparator { |
| | | [self.tabBar layoutIfNeeded]; |
| | | self.tabBar.cyl_tabBadgeBackgroundSeparator.alpha = 0; |
| | | self.tabBar.barStyle = UIBarStyleBlack; |
| | | } |
| | | |
| | | + (BOOL)havePlusButton { |
| | | if (CYLExternPlusButton) { |
| | | return YES; |
| | | } |
| | | return NO; |
| | | } |
| | | |
| | | + (NSUInteger)allItemsInTabBarCount { |
| | | NSUInteger allItemsInTabBar = CYLTabbarItemsCount; |
| | | if ([CYLTabBarController havePlusButton]) { |
| | | allItemsInTabBar += 1; |
| | | } |
| | | return allItemsInTabBar; |
| | | } |
| | | |
| | | - (id<UIApplicationDelegate>)appDelegate { |
| | | return [UIApplication sharedApplication].delegate; |
| | | } |
| | | |
| | | - (UIWindow *)rootWindow { |
| | | UIWindow *result = nil; |
| | | |
| | | do { |
| | | if ([self.appDelegate respondsToSelector:@selector(window)]) { |
| | | result = [self.appDelegate window]; |
| | | } |
| | | |
| | | if (result) { |
| | | break; |
| | | } |
| | | } while (NO); |
| | | |
| | | return result; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark - Private Methods |
| | | |
| | | /** |
| | | * 利用 KVC 把系统的 tabBar 类型改为自定义类型。 |
| | | */ |
| | | - (void)setUpTabBar { |
| | | CYLTabBar *tabBar = [[CYLTabBar alloc] init]; |
| | | [self setValue:tabBar forKey:@"tabBar"]; |
| | | [tabBar cyl_setTabBarController:self]; |
| | | } |
| | | |
| | | - (BOOL)hasPlusChildViewController { |
| | | NSString *context = CYLPlusChildViewController.cyl_context; |
| | | BOOL isSameContext = [context isEqualToString:self.context] && (context && self.context); // || (!context && !self.context); |
| | | BOOL hasPlusChildViewController = CYLPlusChildViewController && isSameContext;//&& !isAdded; |
| | | return hasPlusChildViewController; |
| | | } |
| | | |
| | | - (BOOL)isPlusViewControllerAdded:(NSArray *)viewControllers { |
| | | if ([_viewControllers containsObject:CYLPlusChildViewController]) { |
| | | return YES; |
| | | } |
| | | __block BOOL isAdded = NO; |
| | | [_viewControllers enumerateObjectsUsingBlock:^(UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { |
| | | if ([self isEqualViewController:obj compairedViewController:CYLPlusChildViewController]) { |
| | | isAdded = YES; |
| | | *stop = YES; |
| | | return; |
| | | } |
| | | }]; |
| | | return isAdded;; |
| | | } |
| | | |
| | | - (void)setViewControllers:(NSArray *)viewControllers { |
| | | if (_viewControllers && _viewControllers.count) { |
| | | for (UIViewController *viewController in _viewControllers) { |
| | | [viewController willMoveToParentViewController:nil]; |
| | | [viewController.view removeFromSuperview]; |
| | | [viewController removeFromParentViewController]; |
| | | } |
| | | BOOL isAdded = [self isPlusViewControllerAdded:_viewControllers]; |
| | | BOOL hasPlusChildViewController = [self hasPlusChildViewController] && !isAdded; |
| | | if (hasPlusChildViewController) { |
| | | [CYLPlusChildViewController willMoveToParentViewController:nil]; |
| | | [CYLPlusChildViewController.view removeFromSuperview]; |
| | | [CYLPlusChildViewController removeFromParentViewController]; |
| | | } |
| | | } |
| | | |
| | | if (viewControllers && [viewControllers isKindOfClass:[NSArray class]]) { |
| | | if ((!_tabBarItemsAttributes) || (_tabBarItemsAttributes.count != viewControllers.count)) { |
| | | [NSException raise:NSStringFromClass([CYLTabBarController class]) format:@"The count of CYLTabBarControllers is not equal to the count of tabBarItemsAttributes.【Chinese】设置_tabBarItemsAttributes属性时,请确保元素个数与控制器的个数相同,并在方法`-setViewControllers:`之前设置"]; |
| | | } |
| | | //TODO: |
| | | BOOL isAdded = [self isPlusViewControllerAdded:_viewControllers]; |
| | | BOOL addedFlag = [CYLPlusChildViewController cyl_plusViewControllerEverAdded]; |
| | | BOOL hasPlusChildViewController = [self hasPlusChildViewController] && !isAdded && !addedFlag; |
| | | if (hasPlusChildViewController) { |
| | | NSMutableArray *viewControllersWithPlusButton = [NSMutableArray arrayWithArray:viewControllers]; |
| | | [viewControllersWithPlusButton insertObject:CYLPlusChildViewController atIndex:CYLPlusButtonIndex]; |
| | | _viewControllers = [viewControllersWithPlusButton copy]; |
| | | [CYLPlusChildViewController cyl_setPlusViewControllerEverAdded:YES]; |
| | | } else { |
| | | _viewControllers = [viewControllers copy]; |
| | | } |
| | | CYLTabbarItemsCount = [viewControllers count]; |
| | | CYLTabBarItemWidth = ([UIScreen mainScreen].bounds.size.width - CYLPlusButtonWidth) / (CYLTabbarItemsCount); |
| | | NSUInteger idx = 0; |
| | | for (UIViewController *viewController in _viewControllers) { |
| | | NSString *title = nil; |
| | | id normalImageInfo = nil; |
| | | id selectedImageInfo = nil; |
| | | UIOffset titlePositionAdjustment = UIOffsetZero; |
| | | UIEdgeInsets imageInsets = UIEdgeInsetsZero; |
| | | if (viewController != CYLPlusChildViewController) { |
| | | title = _tabBarItemsAttributes[idx][CYLTabBarItemTitle]; |
| | | normalImageInfo = _tabBarItemsAttributes[idx][CYLTabBarItemImage]; |
| | | selectedImageInfo = _tabBarItemsAttributes[idx][CYLTabBarItemSelectedImage]; |
| | | |
| | | NSValue *offsetValue = _tabBarItemsAttributes[idx][CYLTabBarItemTitlePositionAdjustment]; |
| | | UIOffset offset = [offsetValue UIOffsetValue]; |
| | | titlePositionAdjustment = offset; |
| | | |
| | | NSValue *insetsValue = _tabBarItemsAttributes[idx][CYLTabBarItemImageInsets]; |
| | | UIEdgeInsets insets = [insetsValue UIEdgeInsetsValue]; |
| | | imageInsets = insets; |
| | | } else { |
| | | idx--; |
| | | } |
| | | |
| | | [self addOneChildViewController:viewController |
| | | WithTitle:title |
| | | normalImageInfo:normalImageInfo |
| | | selectedImageInfo:selectedImageInfo |
| | | titlePositionAdjustment:titlePositionAdjustment |
| | | imageInsets:imageInsets |
| | | |
| | | ]; |
| | | [[viewController cyl_getViewControllerInsteadOfNavigationController] cyl_setTabBarController:self]; |
| | | idx++; |
| | | } |
| | | } else { |
| | | for (UIViewController *viewController in _viewControllers) { |
| | | [[viewController cyl_getViewControllerInsteadOfNavigationController] cyl_setTabBarController:nil]; |
| | | } |
| | | _viewControllers = nil; |
| | | } |
| | | } |
| | | |
| | | - (void)setTintColor:(UIColor *)tintColor { |
| | | if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.f) { |
| | | [self.tabBar setSelectedImageTintColor:tintColor]; |
| | | } |
| | | self.tabBar.tintColor = tintColor; |
| | | } |
| | | |
| | | /** |
| | | * 添加一个子控制器 |
| | | * |
| | | * @param viewController 控制器 |
| | | * @param title 标题 |
| | | * @param normalImageInfo 图片 |
| | | * @param selectedImageInfo 选中图片 |
| | | */ |
| | | - (void)addOneChildViewController:(UIViewController *)viewController |
| | | WithTitle:(NSString *)title |
| | | normalImageInfo:(id)normalImageInfo |
| | | selectedImageInfo:(id)selectedImageInfo |
| | | titlePositionAdjustment:(UIOffset)titlePositionAdjustment |
| | | imageInsets:(UIEdgeInsets)imageInsets |
| | | { |
| | | viewController.tabBarItem.title = title; |
| | | if (normalImageInfo) { |
| | | UIImage *normalImage = [self getImageFromImageInfo:normalImageInfo]; |
| | | viewController.tabBarItem.image = normalImage; |
| | | } |
| | | if (selectedImageInfo) { |
| | | UIImage *selectedImage = [self getImageFromImageInfo:selectedImageInfo]; |
| | | viewController.tabBarItem.selectedImage = selectedImage; |
| | | } |
| | | if (self.shouldCustomizeImageInsets || ([self isNOTEmptyForImageInsets:imageInsets])) { |
| | | UIEdgeInsets insets = (([self isNOTEmptyForImageInsets:imageInsets]) ? imageInsets : self.imageInsets); |
| | | viewController.tabBarItem.imageInsets = insets; |
| | | } |
| | | if (self.shouldCustomizeTitlePositionAdjustment || [self isNOTEmptyForTitlePositionAdjustment:titlePositionAdjustment]) { |
| | | UIOffset offset = (([self isNOTEmptyForTitlePositionAdjustment:titlePositionAdjustment]) ? titlePositionAdjustment : self.titlePositionAdjustment); |
| | | viewController.tabBarItem.titlePositionAdjustment = offset; |
| | | } |
| | | [self addChildViewController:viewController]; |
| | | } |
| | | |
| | | - (UIImage *)getImageFromImageInfo:(id)imageInfo { |
| | | UIImage *image = nil; |
| | | if ([imageInfo isKindOfClass:[NSString class]]) { |
| | | image = [UIImage imageNamed:imageInfo]; |
| | | image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; |
| | | } else if ([imageInfo isKindOfClass:[UIImage class]]) { |
| | | image = (UIImage *)imageInfo; |
| | | } |
| | | return image; |
| | | } |
| | | |
| | | - (BOOL)shouldCustomizeImageInsets { |
| | | BOOL shouldCustomizeImageInsets = [self isNOTEmptyForImageInsets:self.imageInsets]; |
| | | return shouldCustomizeImageInsets; |
| | | } |
| | | |
| | | - (BOOL)shouldCustomizeTitlePositionAdjustment { |
| | | BOOL shouldCustomizeTitlePositionAdjustment = [self isNOTEmptyForTitlePositionAdjustment:self.titlePositionAdjustment]; |
| | | return shouldCustomizeTitlePositionAdjustment; |
| | | } |
| | | |
| | | - (BOOL)isNOTEmptyForImageInsets:(UIEdgeInsets)imageInsets { |
| | | if (imageInsets.top != 0 || imageInsets.left != 0 || imageInsets.bottom != 0 || imageInsets.right != 0) { |
| | | return YES; |
| | | } |
| | | return NO; |
| | | } |
| | | |
| | | - (BOOL)isNOTEmptyForTitlePositionAdjustment:(UIOffset)titlePositionAdjustment { |
| | | if (titlePositionAdjustment.horizontal != 0 || titlePositionAdjustment.vertical != 0) { |
| | | return YES; |
| | | } |
| | | return NO; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark - KVO Method |
| | | |
| | | // KVO监听执行 |
| | | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { |
| | | if(context != CYLTabImageViewDefaultOffsetContext) { |
| | | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; |
| | | return; |
| | | } |
| | | if(context == CYLTabImageViewDefaultOffsetContext) { |
| | | CGFloat tabImageViewDefaultOffset = [change[NSKeyValueChangeNewKey] floatValue]; |
| | | [self offsetTabBarTabImageViewToFit:tabImageViewDefaultOffset]; |
| | | } |
| | | } |
| | | |
| | | - (void)offsetTabBarTabImageViewToFit:(CGFloat)tabImageViewDefaultOffset { |
| | | if (self.shouldCustomizeImageInsets) { |
| | | return; |
| | | } |
| | | NSArray<UITabBarItem *> *tabBarItems = self.tabBar.items; |
| | | [tabBarItems enumerateObjectsUsingBlock:^(UITabBarItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { |
| | | UIEdgeInsets imageInset = UIEdgeInsetsMake(tabImageViewDefaultOffset, 0, -tabImageViewDefaultOffset, 0); |
| | | obj.imageInsets = imageInset; |
| | | if (!self.shouldCustomizeTitlePositionAdjustment) { |
| | | obj.titlePositionAdjustment = UIOffsetMake(0, MAXFLOAT); |
| | | } |
| | | }]; |
| | | } |
| | | |
| | | #pragma mark - delegate |
| | | |
| | | - (void)updateSelectionStatusIfNeededForTabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { |
| | | UIButton *plusButton = CYLExternPlusButton; |
| | | CYLTabBarController *tabBarViewController = [[CYLPlusChildViewController cyl_getViewControllerInsteadOfNavigationController] cyl_tabBarController]; |
| | | NSArray *viewControllers = tabBarViewController.viewControllers; |
| | | BOOL isAdded = [self isPlusViewControllerAdded:viewControllers]; |
| | | BOOL hasPlusChildViewController = isAdded; |
| | | BOOL isNotCurrentViewController = ![self isEqualViewController:viewController compairedViewController:CYLPlusChildViewController]; |
| | | BOOL shouldConfigureSelectionStatus = (hasPlusChildViewController && isNotCurrentViewController); |
| | | if (shouldConfigureSelectionStatus) { |
| | | plusButton.selected = NO; |
| | | } |
| | | } |
| | | |
| | | - (BOOL)isEqualViewController:(UIViewController *)viewController compairedViewController:(UIViewController *)compairedViewController { |
| | | if ([viewController isEqual:compairedViewController]) { |
| | | return YES; |
| | | } |
| | | if ([[viewController cyl_getViewControllerInsteadOfNavigationController] isEqual:[compairedViewController cyl_getViewControllerInsteadOfNavigationController]]) { |
| | | return YES; |
| | | } |
| | | return NO; |
| | | } |
| | | |
| | | - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { |
| | | [self updateSelectionStatusIfNeededForTabBarController:tabBarController shouldSelectViewController:viewController]; |
| | | return YES; |
| | | } |
| | | |
| | | - (void)tabBarController:(UITabBarController *)tabBarController didSelectControl:(UIControl *)control { |
| | | } |
| | | |
| | | - (void)didSelectControl:(UIControl *)control { |
| | | SEL actin = @selector(tabBarController:didSelectControl:); |
| | | if ([self.delegate respondsToSelector:actin]) { |
| | | #pragma clang diagnostic push |
| | | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" |
| | | [self.delegate performSelector:actin withObject:self withObject:control]; |
| | | #pragma clang diagnostic pop |
| | | } |
| | | } |
| | | |
| | | - (id)rootViewController { |
| | | CYLTabBarController *tabBarController = nil; |
| | | id<UIApplicationDelegate> delegate = ((id<UIApplicationDelegate>)[[UIApplication sharedApplication] delegate]); |
| | | UIWindow *window = delegate.window; |
| | | UIViewController *rootViewController = [window.rootViewController cyl_getViewControllerInsteadOfNavigationController];; |
| | | if ([rootViewController isKindOfClass:[CYLTabBarController class]]) { |
| | | tabBarController = (CYLTabBarController *)rootViewController; |
| | | } |
| | | return tabBarController; |
| | | } |
| | | |
| | | @end |
| | | |
| | | @implementation NSObject (CYLTabBarControllerReferenceExtension) |
| | | |
| | | - (void)cyl_setTabBarController:(CYLTabBarController *)tabBarController { |
| | | //OBJC_ASSOCIATION_ASSIGN instead of OBJC_ASSOCIATION_RETAIN_NONATOMIC to avoid retain circle |
| | | id __weak weakObject = tabBarController; |
| | | id (^block)() = ^{ return weakObject; }; |
| | | objc_setAssociatedObject(self, @selector(cyl_tabBarController), |
| | | block, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
| | | } |
| | | |
| | | - (CYLTabBarController *)cyl_tabBarController { |
| | | CYLTabBarController *tabBarController; |
| | | id (^block)() = objc_getAssociatedObject(self, @selector(cyl_tabBarController)); |
| | | tabBarController = (block ? block() : nil); |
| | | if (tabBarController && [tabBarController isKindOfClass:[CYLTabBarController class]]) { |
| | | return tabBarController; |
| | | } |
| | | if ([self isKindOfClass:[UIViewController class]] && [(UIViewController *)self parentViewController]) { |
| | | tabBarController = [[(UIViewController *)self parentViewController] cyl_tabBarController]; |
| | | if ([tabBarController isKindOfClass:[CYLTabBarController class]]) { |
| | | return tabBarController; |
| | | } |
| | | } |
| | | id<UIApplicationDelegate> delegate = ((id<UIApplicationDelegate>)[[UIApplication sharedApplication] delegate]); |
| | | UIWindow *window = delegate.window; |
| | | UIViewController *rootViewController = [window.rootViewController cyl_getViewControllerInsteadOfNavigationController];; |
| | | if ([rootViewController isKindOfClass:[CYLTabBarController class]]) { |
| | | tabBarController = (CYLTabBarController *)rootViewController; |
| | | } |
| | | return tabBarController; |
| | | } |
| | | |
| | | @end |