读RDVTabBarController源码记录

RDVTabBarController 是一个定制化的TabBarController库,可动画显示隐藏tabbar栏,可定制tabbar栏,代码库地址在这,效果如下:

iPhone-small.png

用法与UITarbarController差不多,一开始需要设置它的ViewControllers

RDVTabBarController *tabBarController = [[RDVTabBarController alloc] init];
[tabBarController setViewControllers:@[firstNavigationController, secondNavigationController, thirdNavigationController]];

具体的请看github上的介绍。

接下来看看,TabBar栏是怎么被添加到TarbarController的view上,为什么它能在每个ViewController上都能显示的。

首先,在RDVTabBarController类的viewDidLoad方法看到:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self.view addSubview:[self contentView]];
    [self.view addSubview:[self tabBar]];
}

注意添加顺序,先添加contentView,后添加tabBar,这样tabBar栏就不会被contentView覆盖挡住了。此时view的视图层级是这样的:

屏幕快照 2015-08-23 下午3.43.23.png

只要设置一下它们的大小和位置,也就能变成这样:

屏幕快照 2015-08-23 下午3.46.04.png

接着看viewWillAppear方法:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    [self setSelectedIndex:[self selectedIndex]];
    
    [self setTabBarHidden:self.isTabBarHidden animated:NO];
}

先看里面的setSelectedIndex方法:

- (void)setSelectedIndex:(NSUInteger)selectedIndex {
    if (selectedIndex >= self.viewControllers.count) {
        return;
    }
    //第一步
    if ([self selectedViewController]) {
        [[self selectedViewController] willMoveToParentViewController:nil]; //(1)
        [[[self selectedViewController] view] removeFromSuperview]; //(2)
        [[self selectedViewController] removeFromParentViewController]; //(3)
    }
    
    _selectedIndex = selectedIndex;
    [[self tabBar] setSelectedItem:[[self tabBar] items][selectedIndex]];
    //第二步
    [self setSelectedViewController:[[self viewControllers] objectAtIndex:selectedIndex]];
    [self addChildViewController:[self selectedViewController]];(1)
    [[[self selectedViewController] view] setFrame:[[self contentView] bounds]];
    [[self contentView] addSubview:[[self selectedViewController] view]];(2)
    [[self selectedViewController] didMoveToParentViewController:self];(3)
    
    [self setNeedsStatusBarAppearanceUpdate];
}

重点看,第一步,移除上一个所选的ViewController:
(1)willMoveToParentViewController方法,传nil参数表示子视图控制器将被移除;
(2)视图控制器的view从父视图中移除;
(3)子视图控制器从父视图控制器中移除,会自动调用didMoveToParentViewController方法来通知回调。

第二步,添加所选的ViewController:
(1)添加视图控制器,会自动调用willMoveToParentViewController方法;
(2)添加视图控制器的view;
(3)完成添加视图控制器,
要留意的是,是将ViewController的View添加到contentView中,而不是TabBarController的view。而以后push视图控制器的话,都是将视图控制器的view添加到contentView中,这样tabBar就始终能覆盖在contentView之上显示出来。

再看RDVTabBarController类中的setTabBarHidden方法:

- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
    _tabBarHidden = hidden;
    
    __weak RDVTabBarController *weakSelf = self;
    //动画中执行的block
    void (^block)() = ^{
        CGSize viewSize = weakSelf.view.bounds.size;
        CGFloat tabBarStartingY = viewSize.height;
        CGFloat contentViewHeight = viewSize.height;
        CGFloat tabBarHeight = CGRectGetHeight([[weakSelf tabBar] frame]);
        
        if (!tabBarHeight) {
            tabBarHeight = 49;//tabBar默认高度
        }
        
        if (!hidden) {
            tabBarStartingY = viewSize.height - tabBarHeight;
            if (![[weakSelf tabBar] isTranslucent]) {
                contentViewHeight -= ([[weakSelf tabBar] minimumContentHeight] ?: tabBarHeight);
            }
            [[weakSelf tabBar] setHidden:NO];
        }
        
        [[weakSelf tabBar] setFrame:CGRectMake(0, tabBarStartingY, viewSize.width, tabBarHeight)];
        [[weakSelf contentView] setFrame:CGRectMake(0, 0, viewSize.width, contentViewHeight)];
    };
    //动画完成的block
    void (^completion)(BOOL) = ^(BOOL finished){
        if (hidden) {
            [[weakSelf tabBar] setHidden:YES];
        }
    };
    
    if (animated) {
        [UIView animateWithDuration:0.24 animations:block completion:completion]; //执行动画
    } else {
        block();
        completion(YES);
    }
}

这个方法是设置TabBar栏显示或隐藏,所使用的动画比较简单,动画中的block主要设置contentView和tabBar栏的大小和位置。而tabBar栏其实就是一个普通的view,通过设置它的hidden属性,就能让tabBar栏显示或隐藏。

其实,通过分析RDVTabBarController源码,也就明白如何自定义一个容器视图控制器了,同时也能大概明白UITabBarController内部的组织结构了。

最后,请看苹果官方文档:自定义视图控制器容器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 文/烟雨雨巷 翻完萧红的《呼河兰传》,我深深地叹了一口气。怎么说呢,从好奇到悲哀到痛惋,从头至尾都是吊着一口气在那...
    烟雨雨巷阅读 652评论 0 3
  • 有人说,梦想是残烛之光火,现实是缺氧的空气,在现实面前,梦想只是瞬间光火,不可一提。 翻阅起曾经许下的承诺与誓言,...
    雲易少爺阅读 380评论 0 5
  • 作者:赵铁夫 我的心是 山脚下 白云边 湖水旁的 青青草地 朝夕往复 过客来去 终有人会 悄悄地在草地上 拉上一堆...
    赵铁夫阅读 497评论 0 0
  • 今天一直在外忙碌,手机没电啦!刚到家又要去接出差回家的串儿。怕来不及打卡,将之前存的天然酵母,无添加馒头做...
    车前小草阅读 457评论 5 2