导航栏布局
每次涉及到导航栏布局就很难受,总感觉很模糊。
UINavigationController 构成
UIBarItem : NSObject
- UIBarItem 类是一个可以放置在 Bar 之上的所有小控件类的抽象类。
UIBarButtonItem : UIBarItem
- 类似 UIButton 。放在 UINavigationBar 或者 UIToolbar 上。
- 重点属性: customView
UINavigationItem : NSObject
- 包含了当前页面导航栏上需要显示的全部信息
- title、prompt、titleView、leftBarButtonItem、rightBarButtonItem、backBarButonItem
- UIViewController 有一个 navigationItem 属性,通过这个属性可以来设置导航栏上的布局。
UINavigationBar : UIView
- 管理一个存放 UINavigationItem 的栈
小结:
- 设置导航栏上按钮的布局,使用 UIViewController 的 navigationItem 属性来设置其二级 leftBarButtonItem 、 rightBarButtonItem、backBarButonItem、leftBarButtonItems、rightBarButtonItems
- 设置导航栏的背景色就设置 self.navigationController.navigationBar
注意:
- backBarButtonItem 就是我们平时使用的返回箭头后面的按钮,我们通常会设置其 title 为 nil ,这个按钮自带返回事件。如果我们设置了 leftBarButtonItem 或者 leftBarButtonItems ,backBarButonItem 将会失效。
实际布局
UINavigationBar
// 设置导航栏透明
- (void) setNavBarTransparent {
UIImage *image = [UIImage new];
[self.navBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
// 设置导航栏背景色和透明度
- (void) setNavBarAlpha {
UIImage *image = [UIImage imageWithColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:0.5]];
[self.navBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
// 透明并去掉下面的黑线
- (void) setNavBarTransparentAndRemoveSeperator {
[self setNavBarTransparent];
self.navBar.shadowImage = [UIImage new];
}
// 设置背景颜色(设置之后就是不透明,默认是半透明)(很少用)
- (void) setNavBarBarTintColor {
self.navBar.barTintColor = [UIColor whiteColor];
self.navBar.translucent = YES; // 再次设置半透明也是无效的
}
小结:
有些时候你需要设置某种效果时,多看相关属性的注释和当前你设置对象的层次结构。比方说我想设置导航栏全透明,根据属性和接口注释发现给导航栏设置一张全透明的图片为背景图就可以了。但是当设置了之后发现导航栏下面有条黑线,这时候你看看此时导航栏的层次结构,发现有一个 UIImageView ,再去 UINavigationBar 的头文件去看,找到一个 shadowImage 属性,结合它的注释就知道怎么做了。
UINavigationItem
// 不使用 UIButton
// 默认左边距: 非 plus 11+5 | plus 11+9
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:@selector(back)];
leftBarButtonItem.image = [[UIImage imageNamed:@"back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIBarButtonItem *spaceL = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
spaceL.width = -10; // 向左缩进 10 个点
self.navigationItem.leftBarButtonItems = @[spaceL , leftBarButtonItem];
// 使用 UIButton
// 默认左边距: 非 plus 11+5 | plus 11+9
UIBarButtonItem *leftBarButtonItem2 = [[UIBarButtonItem alloc]initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(0, 0, 20, 20)];
[btn setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
leftBarButtonItem2.customView = btn;
UIBarButtonItem *spaceL2 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
spaceL.width = -10; // 向左缩进 10 个点
self.navigationItem.leftBarButtonItems = @[spaceL2 , leftBarButtonItem2];
小结:
- 查看当前视图的层次图时,可以按住 Ctrl 键,再鼠标左键你想查看的子视图,选择 Print 就可以打印其相关信息。
- 不使用 UIButton 进行导航栏布局:
- 需要根据最新的 iOS 图标标准进行切图。比如 iOS 10 导航栏大概是 20px*20px 、 40px*40px 、 60px*60px。
- 需要设置图片的渲染模式。
- 使用 UIButton 进行布局:
- 可以固定图标的大小。
- leftBarButtonItems 是并排布局的,所以我们可以使用 UIBarButtonSystemItemFixedSpace 来进行边距和间距调节。