导航栏显示和隐藏的坑

在iOS开发中,经常需要从一个无NavigationBar的控制器push到一个有NavigationBar的控制器,或者相反。看似只要设置一下NavigationBar的Hidden属性就可以了,其实里面还有不少坑。

隐藏导航栏的方法很简单,只要在控制器将要出现的时候设置NavigationBar隐藏就可以了,然后在控制器将要消失的时候重新显示NavigationBar,效果如图1所示。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // 隐藏导航栏方法1
    self.navigationController.navigationBarHidden = YES;
    // 方法2
//    [self.navigationController setNavigationBarHidden:YES];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    [self.navigationController setNavigationBarHidden:NO];
}
图1.gif

但是仔细观察会发现切换的过程并不顺滑:1.有导航栏的控制器出现时,导航栏会立即出现,而控制器的View是自右向左渐入的(简书其实就是这样的);2.点击返回按钮时,导航栏消失且右侧会出现黑边。如图2所示。

图2.gif

因为在push页面的时候,animated属性是设置成YES的,所以控制器View的出现会有动画。animated属性通常都是设置成YES的,这样的页面切换会让人比较舒服。

[self.navigationController pushViewController:[[HQThirdViewController alloc] init] animated:YES];

所以我们猜想一下,导航栏的显示和隐藏是不是也应该有个animated属性。果不其然,设置导航栏隐藏还有另一个方法可以开启和关闭动画,我们开启动画之后再看看效果,如图3。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:YES];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    
    [self.navigationController setNavigationBarHidden:NO animated:YES];
}
图3.gif

导航栏的显示和控制器的View显示都有动画了,pop的时候也不会出现黑边了。这个animated属性官方是这样解释的:*If animated, it will transition vertically using UINavigationControllerHideShowBarDuration. *意思就是说如果开启动画,导航栏会以某个时长进行垂直过渡。

对于UINavigationControllerHideShowBarDuration官方文档也给出了解释:*This variable specifies the duration when animating the navigation bar. Note that this is a constant value, so it cannot be set. *就是说UINavigationControllerHideShowBarDuration决定了导航栏动画的时长,注意这是一个常量,不能被改变。

这样就完美解决了吗?不,另一个坑出现了。点击TabBarItem进入"我的"页面的时候,导航栏也出现了动画,因为动画只能写在ViewWillAppear方法里,所以每次显示页面都会调用。

图4.gif

现在这种情况下,animated属性肯定是不能开启的,但是pop时候的黑边问题又该怎么解决?

解决方法1
首先想想为什么pop的时候导航栏直接就消失了,因为项目中我把导航栏的translucent属性关闭了(这个属性默认是开启的),控制器的View不会有穿透效果,而pop的时候导航栏隐藏又没有开启动画效果,所以就导致了导航栏直接消失。那么我们再来看看开启translucent属性的效果,如图5。

图5.gif

黑边不会再出现了,导航栏依旧是立即消失,但是控制器的View填充了整个画面。这是一种解决方法,大家可以看看钉钉iOS客户端,从设置页面pop回我的页面也是这种效果。

最后,如果希望Pop的时候导航栏不会立即消失而且没有黑边,切换TabBarItem的时候又不会出现动画,那么依旧还是要开启animated属性的。

解决方法2

1.给"我的"控制器.h文件里添加一个关闭动画的属性

@interface HQMineViewController : UITableViewController

@property (nonatomic, assign) BOOL closeAnimating;

@end

2.在自定义的TabBarController里面实现UITabBarControllerDelegate,并实现如下方法

@interface HQTabBarController ()<UITabBarControllerDelegate>

@end

@implementation HQTabBarController

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
    UINavigationController *navigationController = (UINavigationController *)viewController;
    
    if ([navigationController.topViewController isKindOfClass:[HQMineViewController class]])
    {
        HQMineViewController *mineVc = (HQMineViewController *)navigationController.topViewController;
        // 点击TabBarItem进入"我的"控制器 会关闭导航栏消失的动画
        mineVc.closeAnimating = YES;
    }
    return YES;
}

}

3.修改"我的"控制器中隐藏导航栏的方法

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController setNavigationBarHidden:YES animated:!self.closeAnimating];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self.navigationController setNavigationBarHidden:NO animated:YES];
    
    // 控制器消失时要开启动画,保证由其他方式进入控制器会有动画
    self.closeAnimating = NO;
}

4.最终效果如图6所示

图6.gif

解决方法3
走了这么多的弯路,接下来就放出最终解决方法了,其实只要将animated属性继承ViewWillAppear(Disappear)的animated属性即可,恍然大悟。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [self.navigationController setNavigationBarHidden:YES animated:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

总结

方法3最简单,又能完美解决NavigationBar显示和隐藏切换的问题,顺便简单地实现了tableHeaderView的下拉放大。

代码下载地址

点击进入Github

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 有感 ....请允许我在文章开篇爆句粗口, 就这导航栏错乱这 Bug, 我真日了狗了. 自从测试小伙伴发现这个问...
    李国安阅读 6,377评论 59 108
  • Swift版本点击这里欢迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh阅读 25,254评论 7 249
  • 有个朋友说人家带晚托班的话,一个小孩多少钱算给人家,所以后来我就跟对方说,不想占人家便宜(人家帮忙看孩子的话),最...
    临在一刻阅读 225评论 0 0
  • 蔚来汽车、摩拜董事长给大家讲解《重新定义用户体验》 李斌认为商业化的本质就是差异化用户体验。重新定义用户体验,就能...
    Joycty阅读 859评论 0 1