navigation技巧
[A].获取 导航栏所有的视图控制器
获取 导航栏所有的视图控制器,选择想要跳转的那个视图控制器 可直接传值!无需考虑“反向传值”!!
展示例子🌰:
跳转关系:
MyInfosViewController(我的信息) → VerifyIdentityViewController(验证 旧手机号) → WriteNewPhoneNumberViewController(更改为新手机号)
各界面的层次关系:
修改旧的手机号成功!
跳转到“我的信息”界面,并把新的手机号传到“我的信息”界面!
NSArray *pushVCAry = [self.navigationController viewControllers];
//pushVCAry.count-3 回到MyInfosVC中去
MyInfosViewController *popVC = [pushVCAry objectAtIndex:pushVCAry.count-3]; //(-1:当前层)
//可直接“进行传值”
popVC.transmitPhoneNumberStr = _phoneNumTF.text;
[self.navigationController popToViewController:popVC animated:YES];
也可以直接判断
要跳转回去的ViewController 是否为 “ MyInfosViewController”类型?NSArray *pushVCAry = [weakSelf.navigationController viewControllers]; UIViewController *popVC; for (int i = 0; i < pushVCAry.count; i ++) { if ([pushVCAry[i] isKindOfClass:[MyInfosViewController class] ]) { popVC = pushVCAry[i]; } } //可直接“进行传值” popVC.transmitPhoneNumberStr = _phoneNumTF.text; [self.navigationController popToViewController:popVC animated:YES];
[B].判断在当前UIViewController中,viewWillDisappear的时候是push还是pop:
- (void)viewWillDisappear:(BOOL)animated {
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
NSLog(@"New viewcontroller was pushed");
} else if ([viewControllers indexOfObject:self] == NSNotFound) {
// View is disappearing because it was popped from the stack
NSLog(@"Viewcontroller was popped");
}
}
导航栏 navigationBar
-
系统自带的图标和文字的颜色:(
setTintColor
)[self.navigationController.navigationBar setTintColor:[UIColor whiteColor] ];
-
标题文字的设置:(富文本 ---
setTitleTextAttributes
)[self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]}];
-
半透明属性设置
self.navigationController.navigationBar.translucent = NO;
在iOS 6之前(包括iOS 6) translucent默认就是NO,在iOS 7之后就默认是YES了。
[A].隐藏 导航栏边框下面的黑线
一般:在“viewWillAppear”里(当前界面),隐藏 导航栏边下的黑线;
在“viewWillDisappear”里(下个界面),再显示 导航栏边下的黑线。
方法一
//隐藏 导航栏边下的黑线 [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
方法二
//隐藏 导航栏边下的黑线 self.navigationController.navigationBar.clipsToBounds = YES;
方法三
//获取 某个视图边下的黑线 - (UIImageView *)getNavBlackWithBar:(UIView *)bar { if ([bar isKindOfClass:[UIImageView class]] && bar.frame.size.height < 1) { return (UIImageView *)bar; } for (UIView *views in bar.subviews) { UIImageView *imageView = [self getNavBlackWithBar:views]; if (imageView) { return imageView; } } return nil; }
//获取 导航栏边下的黑线 UIImageView* blackLineImageView = [self getNavBlackWithBar:self.navigationController.navigationBar]; //去掉导航栏边下的黑线 blackLineImageView.hidden = YES;
[B].返回按钮
-
在自己这一层 ,设置 (Push到的)子层的返回按钮。
//自己的返回按钮 self.navigationController.navigationBar.backIndicatorImage = [UIImage imageNamed:@"navbar_icon_back"];//图片 UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil ]; self.navigationItem.backBarButtonItem = item;
自带返回的手势!!!
有时候返回(设置了背景图片)时,会产生卡顿!!!!!
-
解决:在(Push到的)子层 ,设置 返回按钮:
//左侧 返回按钮 UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; //点击按钮 (pop操作) [backButton addTarget:self.navigationController action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside]; /** 设置 背景颜色:方便观察Button的大小 */ //button.backgroundColor = [UIColor grayColor]; /** 设置 图片 */ UIImage *imgForButton = [UIImage imageNamed:@"navbar_icon_back"]; [backButton setImage: imgForButton forState:UIControlStateNormal]; /** 设置 文字 */ NSString *titleStr = @"返回"; [backButton setTitle:titleStr forState:UIControlStateNormal]; //字体大小 backButton.titleLabel.font = [UIFont systemFontOfSize:17.f]; //字体颜色 [backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; /** 尺寸调整 */ backButton.frame = CGRectMake(0, 0 , 100, 100); //硬编码:设置UIButton位置、大小 //文本尺寸 CGSize titleLabelSize = [titleStr sizeWithAttributes:@{NSFontAttributeName:backButton.titleLabel.font}]; //图片尺寸 CGSize buttonImageSize = imgForButton.size; //最终的宽度:文本尺寸的宽度+图片尺寸的宽度 backButton.frame = CGRectMake(0,0,buttonImageSize.width + titleLabelSize.width, buttonImageSize.height); //左侧的leftBarButtonItem,使用返回按钮 UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton]; self.navigationItem.leftBarButtonItem = barButtonItem;
隐藏返回按钮
在上一层 视图控制器 (无字,且 无点击事件响应)
// 隐藏“返回”按钮 可点击(无字,且 无点击事件响应) self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:nil]; //⭐️将“返回”按钮的文字设置不在界面显示 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
在下一层 视图控制器 (直接隐藏)
// 隐藏“返回”按钮 [self.navigationItem setHidesBackButton:YES];
[C].设置 图片背景 setBackgroundImage
使用的图片:
“lucencyNavgationBar_ios7”:透明图片;
“navgationBar_ios7”:蓝色渐变色图片。
基本设置格式:
导航栏、状态栏(作为整体)显示的都是图片!!/** 设置为图片(状态栏+导航栏) */ UIImage * Nav_BG_img = [[UIImage imageNamed:@"navgationBar_ios7"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];//图片 自适应大小 [self.navigationController.navigationBar setBackgroundImage:Nav_BG_img forBarMetrics:UIBarMetricsDefault];
效果:
错误展示:
导航栏背景图片(backgroundImage) 设置为 无图片的image 或 “
nil
”。//设置导航栏背景图片 为 无图片的image [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
或者:
//设置导航栏背景图片 为 nil [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
效果:
总结
-
1.因为导航栏是同一个!而每个界面里导航栏的造型 不同!
设置背景图片,改变导航栏的外观!需要对每个界面出现前(在“-(void)viewWillAppear:(BOOL)animated { }
”里)进行设置!需要“
-(void)viewWillAppear:(BOOL)animated { }
”、“-(void)viewWillDisappear:(BOOL)animated { }
”配合使用!
-
2.使用图片背景来设置界面里导航栏的造型时,不能使用 系统自带的“返回”按钮,不然会出现“跳转卡顿”的现象!
需在每个界面里,设置各界面的“返回”按钮!(在当前层里,设置 “返回”按钮)
让页面导航栏变透明:(背景图片 设置为透明图片)
//透明的图片 [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"lucencyNavgationBar_ios7"] forBarMetrics:UIBarMetricsDefault]; //去掉 透明导航栏边的黑边 [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
效果:
查看视图的层次关系:
一般操作:
在“
-(void)viewWillAppear:(BOOL)animated { }
”里面://透明的图片 [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"lucencyNavgationBar_ios7"] forBarMetrics:UIBarMetricsDefault]; //去掉 透明导航栏边的黑边 [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
在“
-(void)viewWillDisappear:(BOOL)animated { }
”里面,重置:[self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; //显示 透明导航栏边的黑边 [self.navigationController.navigationBar setShadowImage:nil];
对于push到的界面:
根据下个界面的导航栏造型是否改变!
在下个界面的“-(void)viewWillAppear:(BOOL)animated { }
”里,重新设置navigationBar的背景图片!!
[D]. 隐藏导航栏
-
显示 导航栏:
最佳:
[self.navigationController setNavigationBarHidden:NO animated:YES];
不建议:
self.navigationController.navigationBarHidden = NO;
或
self.navigationController.navigationBar.hidden = NO;
显示导航栏 效果:
本层:当前界面
下一层:push到的界面
-
隐藏 导航栏:
最佳:
[self.navigationController setNavigationBarHidden:YES animated:YES];
不建议:
self.navigationController.navigationBarHidden = YES;
或
self.navigationController.navigationBar.hidden = YES;
隐藏导航栏 效果:
本层:当前界面
下一层:push到的界面
使用实例
仅仅在某个视图控制器中,隐藏navigationBar!
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//隐藏 navigationBar
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
//显示 navigationBar
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
效果:
[E]. 适配 导航栏
当前视图控制器里的UIScrollView,自动适配导航栏
self.automaticallyAdjustsScrollViewInsets = NO; //自动适配 导航栏
修改当前视图控制器的“edgesForExtendedLayout
”属性:
self.edgesForExtendedLayout = UIRectEdgeNone; //布局 从导航栏下面开始
将“edgesForExtendedLayout
”属性 设置为UIRectEdgeNone
,那么布局就是从导航栏下面开始!!!
[F]. 背景色设置
基本格式:“setBackgroundColor:
”
展示例子🌰:
[self.navigationController.navigationBar setBackgroundColor:[UIColor blueColor]];
UIImage * Nav_BG_img = [[UIImage imageNamed:@"navgationBar_ios7"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];//图片 自适应大小
[self.navigationController.navigationBar setBackgroundImage:Nav_BG_img forBarMetrics:UIBarMetricsDefault]; //跳转迟钝
但是使用 设置“背景色”,需要配合设置 状态栏的颜色!
barTintColor
涉及到
UIVisualEffectView
!
在界面跳转时,导航栏颜色变化会有UIVisualEffectView
的效果!一般不设置“setBarTintColor
”。展示例子🌰:
[self.navigationController.navigationBar setBarTintColor:[UIColor redColor] ];
“背景图片(backgroundImage)”、“barTintColor” 和 “背景色(backgroundColor)” 的区别: