迷人的 iOS导航条

作者: its程 | 来源:发表于2017-04-09 14:39 被阅读223次

    一、backBarItem和 leftBarItem 傻傻分不清楚

    关于系统的导航条里backBarItem和leftBarItem有什么区别,我看了 LonlyCat 的 iOS 侧滑返回手势,写得还算比较清楚。 自己学习了以后做了个总结,Demo 的内容覆盖还有全局侧滑框架FDFullscreenPopGesture的源码中文详解和自己项目中需求对源码的理解,框架本身代码量也比较少,如果觉得看得吃力可以参考我的 Demo

    1. backBarItem 和 leftBarItem,交互动画区别:
    left and back.gif

    有留意过微信的返回手势效果吗? 微信的返回手势就是第一种,覆盖了 leftBackItem,手势返回的过程中,左上角的文字是渐暗的。

    第二种效果就是 backBarItem 了,也是系统默认的效果,会慢慢远离返回按钮,然后 pop。

    2. backBarItem 和 leftBarItem,代码区别,假如 A要 push B, A --> B
    • leftBarItem:
      在 B 控制器中实现如下代码,就可以覆盖 leftBarItem
    UIButton *lefuButton = [UIButton buttonWithType:UIButtonTypeCustom];
        lefuButton.titleLabel.font = [UIFont systemFontOfSize:17];
        [lefuButton setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateNormal];
        [lefuButton setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateHighlighted];
        [lefuButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [lefuButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
        [lefuButton setImageEdgeInsets:UIEdgeInsetsMake(0, -10, 0, 0)];
        [lefuButton setTitle:@"leftBarItem" forState:UIControlStateNormal] ;
        [lefuButton sizeToFit];
        [lefuButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
        
        UIBarButtonItem *leftButtonItem = [[UIBarButtonItem alloc] initWithCustomView:lefuButton];
        
        self.navigationItem.leftBarButtonItem = leftButtonItem;
    
    • backBarItem:
      在 A(注意这里不是 B) 控制器中实现如下代码,就可以覆盖 backBarItem
     UIBarButtonItem *backItem = [[UIBarButtonItem alloc]init];
        backItem.title = @"backBarItem";
    //如果使用了自己的返回图片, 需要适当调整文字和图片的距离
        [backItem setBackButtonTitlePositionAdjustment:UIOffsetMake(8, 0) forBarMetrics:UIBarMetricsDefault];
        [self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
        self.navigationItem.backBarButtonItem = backItem;
    

    如果仅仅在 A 控制器中覆盖 backBarButtonItem 的话,那 B 控制器中的返回图片还是系统的, 如果想要替换成自己的返回图片,就要在导航控制器中添加如下代码,替换系统的backIndicatorImage

     UIImage *backImg = [UIImage imageNamed:@"nav_back"];
        backImg = [backImg imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        self.navigationBar.backIndicatorImage = backImg;
        self.navigationBar.backIndicatorTransitionMaskImage = backImg;
        
    
    
    3. backBarItem 和leftBarItem , 在项目应用中的区别:
    • 覆盖leftBarItem

    系统自带的边缘侧滑手势会失效,需要重新在导航控制器中设置边缘返回手势的代理为某个对象,可以在代理中处理边缘侧滑手势

        self.interactivePopGestureRecognizer.delegate =  someObject;
    

    优点当然是可以更灵活的处理 leftBarItem的点击事件和 UI 方面;

    • 覆盖backBarItem

    系统自带的边缘侧滑手势会不会失效,但是想要灵活的处理 backBarItem 的事件那就不行了。

    二、关于FDFullscreenPopGesture

    这个 sunny 开源的框架,解决了无论是覆盖 leftBarItem 还是 backBarItem 的返回手势问题, 并且把边缘返回手势,改变成了全局返回手势,同时解决了控制器之间存在导航条是透明的情况,不同控制器之间的无缝衔接。

    整个框架运用分类 + runtime 的写完,不用写一行代码就可以实现全局返回手势,因为 runtime 会调用分类的+load 方法,而且是后于类和子类调用。框架效果图如下:

    FDFullScreen.gif

    但是在实际开发中我的项目在导航条需要隐藏的控制器中,往下滑动时候,导航条还需要渐变,因为FDFullscreenPopGesture 是通过

    self.fd_prefersNavigationBarHidden = YES;
    

    这个控制器的属性来隐藏导航条的,如果再在导航条上加上透明度渐变的效果,那来回 pop,push 其他控制器的时候根本无法好好处理导航条的隐藏和显示,所以我在 demo 中,在需要渐变导航条的控制器中添加了一个假的导航条,这是一个很好的解决方式。

    MYFDFullScreen.gif

    附上Demo, Demo 中附有FDFullscreenPopGesture源码中文详解,因为源代码为了简洁和方便,把所有分类都放到一个文件中,我为了能让其更简单易懂,就把各个分类文件能分开就分开了, 虽然文件多了但是结构更加清晰。

    相关文章

      网友评论

        本文标题:迷人的 iOS导航条

        本文链接:https://www.haomeiwen.com/subject/jthdattx.html