zoukankan      html  css  js  c++  java
  • NavigationController 已经洗干净了, 就等你来

    一. 基本属性

    • 设置颜色

      如果项目中 Navigation 都是统一的,而你又懒得单独抽取一个BaseNavigationController,可以直接在 [appDelegate didFinishLaunchingWithOptions]方法中写

    //设置NavigationBar背景颜色
    [[UINavigationBar appearance] setBarTintColor:[UIColor redColor]];
    
    // 通过富文本设置title 样式(这里也可以通过自定义Label,然后设置 titleView 来实现)
    [[UINavigationBar appearance] setTitleTextAttributes:@{
                        NSForegroundColorAttributeName : [UIColor whiteColor]
                                                               }];
    
    // 设置状态栏格式,如果 NavigationBar 为深色调,就设置为 UIBarStyleBlack,则状态栏显示为白色
    [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
    • 实现 NavigationBar 透明效果

      实现透明可能大家第一个想到的是 设置 alpha 值,但是由于设置了作为父控件的 NavigationBar 的透明度后,其子控件 BarButtonItem 也会随之改变,因此想要实现导航栏透明,但是 BarButtonItem 正常显示(类似 手机QQ 的好友动态页),可以采用下面的方法

      // 设置一个空的图片背景图片,就能实现导航栏透明但是 BarButtonItem 正常显示
      [self.navigationController.navigationBar setBackgroundImage:[UIImage new]
                                                    forBarMetrics:UIBarMetricsDefault];

      然而设置之后乍一看没问题,可仔细一看你会发现NavigationBar下面还有一条细线,这个细线就是shadow

      快看那条淡淡的细线!

      层级关系图

    可通过以下代码来去掉

    // 设置一个空的 shadowImage 来实现
    self.navigationController.navigationBar.shadowImage = [UIImage new];

    那么有同学可能要问了,一直透明的可以通过上述方法来实现,那如果想要随着 上拉距离的改变,实现其透明度动态变化要怎么做?

    // 这个就要监听 scrollView 的 offset
    // 然后获取到 NavigationBar复合视图 的显示子控件,动态改变其透明度
    [[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = 0;

    既然讲到这里了就说下来回 push 或 pop,以及使用手势来返回的时候,上下层级之间 NavigationBar 隐藏与否的设置,因为如果这里没处理好的话,会有一个黑条,或者直接显示下一层级的视图,体验特别差,这时候就需要通过动画的方式的在下一层级进行设置

    - (void)viewWillAppear:(BOOL)animated{
        [super viewWillAppear:animated];
        // 当前 VC 需要显示 navigationBar 就设置为 NO,需要隐藏就设置为 YES
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    }
    • 侧滑手势相关

      很多时候,leftBarButtonItem需要自定义,因为默认的显示上一层级的title不一定是我们想要的,但是自定义改变之后,会发现侧滑返回的手势不好使了

    #warning 这时候就需要在当前 VC 中设置手势代理了
    self.interactivePopGestureRecognizer.delegate = self;
    
    // 实现代理方法:返回 YES,则手势有效
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
        //当导航控制器的子控制器个数 大于1 手势才有效
        return self.childViewControllers.count > 1;
    }
    • 由于项目中同一个 VC,有时候是 modal 出来的,有时候是 push 出来的,那么在这个VC中就要判断进行处理

      NSArray *viewcontrollers=self.navigationController.viewControllers;
      if (viewcontrollers.count > 1) {
        if ([viewcontrollers objectAtIndex:viewcontrollers.count - 1] == self) {
            // push方式
            [self.navigationController popViewControllerAnimated:YES];
        }
      } else {    
        // present方式    
        [self dismissViewControllerAnimated:YES completion:nil];
      }
    • 如果要实现如下效果的导航栏,设置 leftBarButtonItems 和 rightBarButtonItems 即可

      喂!焦点在 NavigationBar,老看 tableView 干啥!

    • 关于 rootVC 的 offset,先来看几个 ViewController 的属性

      • iOS7以后默认设置是 UIRectEdgeAll,translucent 的默认值是 true,这个组合会使 rootView 的布局从 (0, 0) 开始,就会造成 rootView 被 NavigationBar 遮挡住一部分,将 edgesForExtendedLayout 设置为 UIRectEdgeNone 即可解决问题
      • automaticallyAdjustsScrollViewInsets 默认值是 YES,表示在全屏下会自动将 第一个添加到 rootVC 的 ScrollView 的 contentInset 设置为 (64, 0, 0, 0),这样 scrollView 就不会被导航栏遮挡住了

    二. 来回跳转

    项目中有个需求是A push 到 B, B push 到 C, C pop 到 D,D 再 pop到 A,就好比这样:

    类似这种交叉跳转的感觉

    • 首先 A push 到 B,直接使用
      [self.navigationController pushViewController:B animated:YES];
      // 此时 self.navigationController.childViewControllers = [A, B];
    • 然后 B push 到 C,同理
      [self.navigationController pushViewController:C animated:YES];
      // 此时 self.navigationController.childViewControllers = [A, B, C];
    • 现在要实现 C pop 到 D,由于 navigationController.childViewControllers 是只读的,因此不能直接对其进行操作

      navigationController.childViewControllers 是只读的

    // 建立可变拷贝对象,然后进行替换操作
    NSMutableArray *navChildMArr = [self.navigationController.childViewControllers mutableCopy];
    [navChildMArr replaceObjectAtIndex:1 withObject:D];
    
    // 当然,最后再将替换后的数组赋值回去不要忘了
    [self.navigationController setViewControllers:navChildMArr animated:YES];
    
    #warning 至于写上面这串代码的时机:写在 B push C 之后可以,写在 C 的 viewDidLoad() 方法中也可以

    最后的效果如图

    对,效果如图

    就四这么简单!

    如果有其他问题,可以在留言处写下来,不定期更新

    来自:http://www.jianshu.com/p/a1a0c053fb12

    最怕你一生碌碌无为 还安慰自己平凡可贵
  • 相关阅读:
    iot 表索引dump《2》
    heap表和iot表排序规则不同
    Cannot complete the install because one or more required items could not be found.
    iot表输出按主键列排序,heap表不是
    iot 表主键存放所有数据,且按数据插入顺序排序
    iot表和heap表排序规则不同
    org.eclipse.graphiti.ui.editor.DiagramEditorInput.
    Oracle 排序规则
    perl 异步超时 打印错误
    14.6.3 Grouping DML Operations with Transactions 组DML操作
  • 原文地址:https://www.cnblogs.com/fakeCoder/p/5093731.html
Copyright © 2011-2022 走看看