IOS 关于UINavigationController的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sky_long_fly/article/details/86482508

前言

最近理了一下UINavigationBar,发现UINavigationController使用的时候有很多问题。所以结合自己使用的理解,总结一下。
UINavigationController 用来管理 UIViewController(视图控制器),它以栈的形式管理,UIViewController个数理论上不受限制(当然内存还是要考虑的),push和pop方法来弹入弹出UIViewController。虽然UINavigationController是UIViewController的子类,但是UINavigationController是不能被push方法打开的。只能被UINavigationController 父类函数presentViewController:弹出。

函数说明

初始化函数说明 UINavigationController 最少有一个UIViewController 在底部。

- (instancetype)initWithRootViewController:(UIViewController *)rootViewController; // Convenience method pushes the root view controller without animation.

1. 打开视图控制器

UINavigationController常用push 函数来打开一个UIViewController

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;

UINavigationController 还支持一次性打开多个UIViewController (底控制器->(VC1 、VC2 、VC3)) ,但是最后一个UIViewController在最上面。业务场景很少用这个函数。

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated;

2.关闭视图

关闭当前控制器

- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated;

关闭多个视图控制器


- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;

关于关闭多个控制器实际场景中会出现 ,关闭到指定的UIViewController。可以使用

@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;

先获取所有打开过的UIViewController,然后找到目标UIViewController,然后使用函数popToViewController,就可以关闭到指定的界面。(当然关闭的这个界面必须是在 viewControllers 中的)

-(void)popToViewController:(Class)vcClass animated:(BOOL)animated{
    UINavigationController * navigationC = self.navigationController;
    if (navigationC){
        for (UIViewController *tempVC in navigationC.viewControllers) {
            if ([tempVC isKindOfClass:vcClass]) {
                [navigationC popToViewController:tempVC animated:animated];
                break;
            }
        }
    }
}

如果要关闭的UIViewController 没有在当前 UINavigationController怎么办呢?当然有办法的,UINavigationController是不能被push 的,所以我们可以查看 presentedViewController 属性,一层一层的查找到你所需要的关闭的UIViewController。

3.和UITabBarController一起使用

我们大多数App主界面样式UITabBarController 。但是和UINavigationController不同的配合会产生不同的交互效果,当然这也关系到 UINavigationController 的使用。

第一种使用方式 (代表App 微信)
   UITabBarController *tabBarVC = [[UITabBarController alloc] init];
    UIViewController *firstVC = [[UIViewController alloc] init];
    firstVC.tabBarItem.title = @"首页";
    UIViewController *secondVC = [[UIViewController alloc] init];
    secondVC.tabBarItem.title = @"我的";
    tabBarVC.viewControllers = @[firstVC,secondVC];
    UINavigationController * navigationVC = [[UINavigationController alloc] initWithRootViewController:tabBarVC];
    self.window.rootViewController = navigationVC;
第二种使用方式 (代表App AppStore 、照片)
      UITabBarController *tabBarVC = [[UITabBarController alloc] init];
    
    UIViewController *firstVC = [[UIViewController alloc] init];
    UINavigationController * firstNavigationVC = [[UINavigationController alloc] initWithRootViewController:firstVC];
    firstNavigationVC.tabBarItem.title = @"首页";
    
    UIViewController *secondVC = [[UIViewController alloc] init];
    UINavigationController * secondNavigationVC = [[UINavigationController alloc] initWithRootViewController:secondVC];
    secondNavigationVC.tabBarItem.title = @"我的";
    tabBarVC.viewControllers = @[firstNavigationVC,secondNavigationVC];
   
    self.window.rootViewController = tabBarVC;

有兴趣大家可以做一个dome 或者直接看一下我推荐的App 看一下就能够明白。大家可以根据实际场景来选择代码实现方式。

4.顶部UIViewController 中 navigationItem 的控制

当我们根据实用场景选择 3 的一种方式后,接下来给我们带来的问题就是 navigationItem的设置问题。

第一种使用方式 (代表App 微信)

这种方式设置navigationItem 的时候由于 UINavigationController的根视图(rootViewController)是 UITabBarController,所以设置 navigationItem 的时候是根据UITabBarController的属性selectedIndex来更换设置其navigationItem。我们利用这种方式来实现切换底部tabbar,头部的navigationItem 变化的效果。

第二种使用方式 (代表App AppStore 、照片)

这种方式设置navigationItem 的时候 UITabBarController 中包含 UINavigationController,UINavigationController的根视图(rootViewController)是其tabbar 切换的不同UIViewController。所以直接在UIViewController设置navigationItem即可。

这一部分强烈建议大家去做一个dome 加深一下印象。

5.关于UINavigationBar 和 UIBarButtonItem 设置

    //应用中所有navigationBar 修改默认配置
    [UINavigationBar appearance].translucent = YES;
    [[UINavigationBar appearance] setTintColor:[UIColor blackColor]];
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"clearbg.png"] forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setShadowImage:[UIImage imageNamed:@"clearbg.png"]];
    [[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor]}];//设置title颜色
    //返回按钮设置
    [UINavigationBar appearance].backIndicatorImage = [UIImage imageNamed:@"Titlebackbg.png"];
    [UINavigationBar appearance].backIndicatorTransitionMaskImage = [UIImage imageNamed:@"Titlebackbg.png"];
    
    
    //设置按钮颜色
    [[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor],NSFontAttributeName:[UIFont systemFontOfSize:14.0]} forState:UIControlStateNormal];
    [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName: [UIColor redColor]} forState:UIControlStateNormal];
    [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName: [UIColor blackColor]} forState:UIControlStateHighlighted];
    [[UIBarButtonItem appearance] setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName: [UIColor colorWithWhite:0 alpha:0.5]} forState:UIControlStateDisabled];

6.关于返回的设置

设置返回不带文字
 self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleDone target:nil action:nil];

最好的方式是利用runtime 在 UIViewController 的 viewDidLoad函数中实现以上代码。

获取返回按钮的事件

代码传送门

猜你喜欢

转载自blog.csdn.net/sky_long_fly/article/details/86482508