navigation-bar的黑魔法

平时我们在处理页面跳转的时候有一个非常难受的情景,就是当两个页面的导航栏背景色不一致的时候,系统不能很好的处理这两者间的交互动画,这就导致整个导航栏的背景转换非常的生硬,那么这里就来看看现在的一些主流的处理方式。

自定义navigationBar

在每个Controller的内部自己实现一个navigation bar,来替代系统UINavigationController的bar。

这种方式最简单直接,也不需要考虑太多的兼容措施和特殊情况。但是这种方式太繁琐,同时和系统的特性相差比较多,不太利于以后的移植和扩展。

要简化这种方式可以定义一个基类,包含实现navigationBar,其他都继承于该基类:

@interface BaseViewController: UIViewController
@property (readonly, strong, nonatomic) UINavigationBar *navigationBar;
@end

转换NavigationBar的background

像微信这种,导航栏的按钮等动效还是和系统一致,但是背景动效却是跟随页面的。其实是伪装了部分navigationBar。

\----------------\
 \ navigation bar \
  \----------------\
\------------------------\
 \ navigation bacckground \
  \------------------------\
   \          view          \
    \------------------------\

在每次设置navigation background相关属性的时候,自动为其转入到一个第三方的background view中实现。而系统的navigation bar永远是透明的,所以看到的永远是在下面的假的背景。这里要注意的是,需要将这个background永远放在最上层的视图。

这里background有两种方式实现,比如微信,是直接生成一个UINavigationBar,而有些库则是截屏然后渲染为image对象来展示。不管哪种方式,其思想都是一致的。

这种方式和第一种方式类似,只是将部分(背景)放到了view中实现,这种方式既符合了系统的编写方式,又简化了实现的方式,是一种比较好的方式。甚至可以两者结合起来,设置背景的时候不要调用self.navigationController.navigationBar,而调用上面的self.navigationBar

多层嵌套NavigationController

上面的方式都是制造了一个假的navigationBar来解决这类问题,这个方式是完全的使用系统特性来解决这个问题,比如云音乐就是这样的。

既然UINavigationController自带navigationBar,那么我们为什么不利用这个特性呢。我们每次push进去的不是一个单纯的UIViewController,而是一个UINavigationController

- (void)pushViewController:(UIViewController *)controller animated:(BOOL)animated {
  UINavigationController *navi = [[UINavigationController alloc] initWithRootController:controller];
  [super pushViewController:navi animated:animated];
}

这样我们虽然使用的是系统方式,然而我们push进去的是一个UINavigationController

这种方式所得到的navigation bar是真正的系统特性,无需做任何的适配。但这种方式也给整个结构带来了破坏,这里来说说:

push进去的是一个controller,而从self.navigationController.viewControllers中取出来的却并不一致,也就产生了api含义的不对称性。如果你要判断上一个Controller是什么页面就会比较麻烦了。当然这种不对称性可以通过重写方法来解决,但还是在使用者无感知的情况下,破坏了其整体结构:

- (NSArray *)viewControllers {
  return [[super viewControllers] map:^(UINavigationController *navi){
    return navi.rootController;
  }];
}

总结

就以上几种方式来看,本人更倾向于第二种方式,既按照系统的特性来,有避免了改动系统结构,对系统api的含义转换我还是比较谨慎的,副作用会让人感到疑惑和难以察觉。

如果你还有其他的方式,可以告诉我。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,251评论 4 61
  • 本文为大地瓜原创,欢迎知识共享,转载请注明出处。虽然你不注明出处我也没什么精力和你计较。作者微信号:christg...
    大地瓜123阅读 745评论 0 0
  • 我叫李婷今年19岁,17岁和我老公结的婚18岁生的我儿子,19岁离得婚。感觉我的婚姻就像雷阵雨一样匆匆的来又匆匆的...
    影子hy阅读 451评论 0 0
  • 准备 出发啦 一个接一个排队有秩序上校车 坐在校车上,孩子们一路上欢声笑语,又唱又笑,还认识各种标志,过红绿灯了,...
    wly媛阅读 213评论 0 0
  • 人为什么要努力? 一位长者告诉我:"适者生存。" 其实,岁月只能给你风尘满面,而希望,唯有努力才能得到。 网上有这...
    七点十二分阅读 148评论 4 5