自定义UITabBar——移除自带UITabBarButton

网上实现自定义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的诡异情况
    自定义UITabBar——移除自带UITabBarButton_第1张图片

    自定义UITabBar——移除自带UITabBarButton_第2张图片
    切换后的自动添加

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

// CYTabBar.h
#import 

@interface CYTabBar : UITabBar

@end
@implementation CYTabBar

- (NSArray *)items {
    return @[];
}
// 重写,空实现
- (void)setItems:(NSArray *)items {
}
- (void)setItems:(NSArray *)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中为所欲为了!


自定义UITabBar——移除自带UITabBarButton_第3张图片

最后还有点友情提示,尽量不要以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)