美文网首页小知识点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