美文网首页小知识点iOS精品文章
自定义UITabBar——移除自带UITabBarButton

自定义UITabBar——移除自带UITabBarButton

作者: 吸氧 | 来源:发表于2017-11-26 17:31 被阅读181次

网上实现自定义UITabBarController的文章多如牛毛,实现的方法也大同小异。关键是如何实现一个客制化的UITabBar,去除默认生成的UITabBarButton

较普遍的做法是,在UITabBarControllerviewWillLayoutSubviews方法中遍历tabBar的子视图,将其中的UITabBarButton一一去除。

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];    
    for (UIView *child in self.tabBar.subviews) {
        if ([child isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            [child removeFromSuperview];
        }
    }
}

这样做的问题有两个:

  1. 效率低下,不作限制的话UITabBarController生命周期内还会多次调用
  2. UITabBarController的子视图控制器有设置title等属性时,还会在切换视图页面出现重新添加UITabBarButton的诡异情况

    切换后的自动添加

这种情况猜测是UITabBarController在改变selectedIndex的同时,会刷新UITabBarUITabBarItem列表items,同时根据items进行刷新布局。既然有了大概猜想,解决方案自然随之而生:将items置空,并阻止添加就好了。

// CYTabBar.h
#import <UIKit/UIKit.h>

@interface CYTabBar : UITabBar

@end
@implementation CYTabBar

- (NSArray<UITabBarItem *> *)items {
    return @[];
}
// 重写,空实现
- (void)setItems:(NSArray<UITabBarItem *> *)items {
}
- (void)setItems:(NSArray<UITabBarItem *> *)items animated:(BOOL)animated {
}

@end

再靠KVC把UITabBarController中的tabBar替换掉。

// UITabBarController子类
CYTabBar *cyTabBar = [[CYTabBar alloc] init];
cyTabBar.frame = self.tabBar.bounds;
[self setValue: cyTabBar forKey:@"tabBar"];

大功告成,可以在自己的tabBar中为所欲为了!


最后还有点友情提示,尽量不要以UITabBarController作为UINavigationController的根视图控制器。该情况下UITabBarController切换子页面时会产生视图控制器视图高度不对的问题,公用的NavigationBar也将变得难以控制。

//Don't do this
UIViewController *ctrl1 = [[UIViewController alloc] init];
UIViewController *ctrl2 = [[UIViewController alloc] init];
UIViewController *ctrl3 = [[UIViewController alloc] init];

UITabBarController *ctrl = [[UITabBarController alloc] init];
[ctrl setViewControllers:@[ctrl1, ctrl2, ctrl3] animated:NO];

UINavigationController *navCtrl =[[UINavigationController alloc] initWithRootViewController: ctrl];
[self presentViewController:navCtrl animated:YES completion:nil];
// Do this
UIViewController *ctrl1 = [[UIViewController alloc] init];
UINavigationController *navCtrl1 =[[UINavigationController alloc] initWithRootViewController: ctrl1];
UIViewController *ctrl2 = [[UIViewController alloc] init];
UINavigationController *navCtrl2 =[[UINavigationController alloc] initWithRootViewController: ctrl2];
UIViewController *ctrl3 = [[UIViewController alloc] init];
UINavigationController *navCtrl3 =[[UINavigationController alloc] initWithRootViewController: ctrl3];

UITabBarController *ctrl = [[UITabBarController alloc] init];
[ctrl setViewControllers:@[navCtrl1, navCtrl2, navCtrl3] animated:NO];

[self presentViewController:ctrl animated:YES completion:nil];

最后的最后再推荐一个TabBarController的开源库,在学习源码的过程中让我获益匪浅:ChenYilong/CYLTabBarController

讲完,以上。

相关文章

网友评论

本文标题:自定义UITabBar——移除自带UITabBarButton

本文链接:https://www.haomeiwen.com/subject/ssnkbxtx.html