iOS

iOS-UINavigationController基本使用

2021-06-28  本文已影响0人  h2coder

UINavigationController是iOS提供的栈视图控制器,它必须设置一个RootViewController根控制器,页面跳转时,通过它将下一个子ViewController的视图添加到RootViewController的视图中。

在Android中,可以联想到Activity和Fragment,它们都使用了栈来管理视图,而UINavigationController更加类似于Fragment,因为Activity之间的跳转是2个Window之前的切换,前页面布局和后页面的布局是没有关联的,而Fragment和UINavigationController一样,Fragment和Fragment之间的嵌套,是同一个Window下的布局视图之间的嵌套。

但Fragment的Bug和坑太多了,例如点击穿透,内存重启后重影,Fragment弹栈到根Fragment并不能清除根以上的Fragment实例等。所以一般Fragment不做栈跳转,而是内嵌到Activity和Fragment之间嵌套来使用。

UINavigationController示例.png

本篇来介绍一下UINavigationController的3个方面:

  1. UINavigationController创建和基本配置
  2. UINavigationBar导航栏样式
  3. UINavigationController的栈管理API
  4. UIToolbar底部工具栏样式

UINavigationController创建和基本配置

本篇都是用纯代码方式,不使用Storyboard,所以记得在info.plist文件中删除掉MainStoryboard的设置。

//创建根视图控制器
ViewController* rootVC = [[ViewController alloc] init];
UINavigationController* navVC = [[UINavigationController alloc] initWithRootViewController:rootVC];
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    //创建根视图控制器
    ViewController* rootVC = [[ViewController alloc] init];
    //创建UINavigationController,将根视图控制器作为它的根视图
    UINavigationController* navVC = [[UINavigationController alloc] initWithRootViewController:rootVC];
    //设置window的根视图控制器为UINavigationController
    self.window.rootViewController = navVC;
    //显示Window
    [self.window makeKeyAndVisible];
    return YES;
}

UINavigationBar导航栏样式

经过上面的创建和配置,我们的ViewController视图控制器已经被UINavigationController控制了,我们会发现ViewController的视图上有一个导航栏,它就是UINavigationBar。

UINavigationBar是由UINavigationController管理的,但是它的样式由子控制器的self. navigationItem来设置。下面来说一下它的样式配置和按钮的添加。

//设置导航栏标题
self.title = @"根视图";
//设置导航元素项目的标题,如果没有设置self.navigationItem.title,系统会使用self.title作为导航栏的标题
//self.navigationItem.title = @"我也是标题";

UINavigationBar导航栏默认是透明的,控制器视图从设备的左上角(0,0)点开始计算,而UINavigationBar覆盖在控制器视图以上,我们可以设置它为不透明,不透明时,控制器视图从导航栏之下开始计算。

//设置导航栏是否透明,默认为YES: 透明,NO则为不透明
//如果不设置该属性,导航栏和视图控制器的View会重合,形成半透明
self.navigationController.navigationBar.translucent = NO;
//设置导航栏风格
//UIBarStyleDefault: 默认风格
//UIBarStyleBlack:黑色风格

//第一种,将所有的UINavigationController都统一设置(UINavigationController可以有多个)
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

//第二种,只在调用的UINavigationController上设置
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
//设置导航栏颜色,该属性会将上面的透明属性和BarStyle进行覆盖
self.navigationController.navigationBar.barTintColor = [UIColor redColor];
//设置导航栏上的元素颜色风格,例如影响导航栏上的文字颜色
self.navigationController.navigationBar.tintColor = [UIColor orangeColor];
//隐藏导航栏,设置为YES则隐藏掉导航栏,这个属性是UIView上面的属性
self.navigationController.navigationBar.hidden = YES;
//或者导航控制器上的属性也可以隐藏
self.navigationController.navigationBarHidden = YES;

UINavigationBar导航栏添加按钮

导航栏除了标题外,还可以摆放元素,常见就是添加操作按钮和返回按钮,也可以放置自定义的元素。

导航栏上的按钮需要使用UIBarButtonItem,来包裹我们自定义内容或者自定义视图。

按钮风格可以分为3种,文字按钮、系统图片按钮和自定义视图,文字按钮通过initWithTitle来设置,系统图片按钮则是通过initWithBarButtonSystemItem,最后自定义视图使用initWithCustomView。

//创建一个导航栏左侧按钮
//参数一:按钮标题
//参数二:按钮风格
//参数三:事件拥有者
//参数四:按钮事件
UIBarButtonItem* leftBtn = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStyleDone target:self action:@selector(pressLeft:)];
//设置到导航栏上
self.navigationItem.leftBarButtonItem = leftBtn;

/**
 * 左侧按钮点击事件回调方法
 */
- (void) pressLeft:(UIBarButtonItem*)btn {
    NSLog(@"左侧按钮被按下");
}
//创建一个导航栏右侧按钮,使用系统风格来创建,无需标题文字,因为它不能被改变
UIBarButtonItem* rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(pressRight:)];
//设置到导航栏上
self.navigationItem.rightBarButtonItem = rightBtn;

/**
 * 右侧按钮点击事件回调方法
 */
- (void) pressRight:(UIBarButtonItem*)btn {
    NSLog(@"右侧按钮被按下");
}
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 40, 40)];
label.text = @"测试";
label.textColor = [UIColor grayColor];
label.textAlignment = NSTextAlignmentCenter;
//将Label包装为UIBarButtonItem
UIBarButtonItem* labelItem = [[UIBarButtonItem alloc] initWithCustomView:label];
//省略上面系统图片风格按钮和自定义View按钮的创建和初始化...

//将多个按钮放置到NSArray数组中,再添加到导航栏的位置
NSArray* arrays = [NSArray arrayWithObjects: rightBtn, labelItem, nil];
//设置多个按钮到导航栏上
self.navigationItem.rightBarButtonItems = arrays;

默认子控制器的导航栏左侧的是返回键按钮,如果需要改变它,有2种方式,第一种就是上面说到的使用self.navigationItem.leftBarButtonItem来设置,第二种是设置self.navigationItem.backBarButtonItem属性。leftBarButtonItem的优先级大于backBarButtonItem。

  1. 第二种,在跳转前的控制器中设置self.navigationItem.backBarButtonItem属性,如果设置了,下一个控制器页面的返回键则使用backBarButtonItem属性设置的。
//设置下个页面的返回按钮
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"首页" style:(UIBarButtonItemStyleDone) target:nil action:@selector(backToMy)];

/**
 * 返回当前控制器
 */
- (void) backToMy {
    [self.navigationController popToViewController:self animated:YES];
}

UINavigationController的栈管理API

除了上面的设置按钮,UINavigationController最重要的还是栈容器管理视图控制器,下面来了解一下栈方面的Api。

首先先创建下一个控制器SecondViewController的实例,再通过控制器上的self.navigationController,调用pushViewController方法,将SecondViewController推入栈中,第二个animated参数代表是否需要跳转动画。

//创建下一个页面的ViewController
SecondViewController* nextVC = [[SecondViewController alloc] init];
//跳转到下一个页面
[self.navigationController pushViewController:nextVC animated:YES];
//创建2个视图控制器
OneViewController *oneVC = [[OneViewController alloc] init];
TwoViewController *twoVC = [[TwoViewController alloc] init];
//将2个视图控制器放到数组中
NSArray *vcArray = [[NSArray alloc] initWithObjects:oneVC,twoVC, nil];
[self.navigationController setViewControllers:vcArray animated:YES];
[self.navigationController popViewControllerAnimated:YES];
[self.navigationController popToViewController:targetVC animated:YES];

UIToolbar底部工具栏样式

UINavigationController还附带一个工具栏,默认是隐藏的,而且也比较少用

//是否隐藏工具栏,默认为YES,默认隐藏
self.navigationController.toolbarHidden = NO;
//设置工具栏透明度为透明
self.navigationController.toolbar.translucent = NO;
//创建2个工具栏按钮
UIBarButtonItem* btn01 = [[UIBarButtonItem alloc] initWithTitle:@"点赞" style:UIBarButtonItemStyleDone target:nil action:nil];
UIBarButtonItem* btn02 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil];
//将按钮放到数组里
NSArray* toolBtns = [NSArray arrayWithObjects:btn01, btn02, nil];
//添加到工具栏
self.toolbarItems = toolBtns;
//创建2个工具栏按钮
UIBarButtonItem* btn01 = [[UIBarButtonItem alloc] initWithTitle:@"点赞" style:UIBarButtonItemStyleDone target:nil action:nil];
UIBarButtonItem* btn02 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil];

//-------------- 自动平分按钮(重点在这里!!!) --------------
UIBarButtonItem* btnSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

//将按钮放到数组里
NSArray* toolBtns = [NSArray arrayWithObjects:btnSpace, btn01, btnSpace, btn02, btnSpace, nil];
//添加到工具栏
self.toolbarItems = toolBtns;
上一篇下一篇

猜你喜欢

热点阅读