一、设置导航栏样式
设置导航栏的样式可分为全局设置与局部设置;
1.全局设置
全局设置一般的都是在appdelegate中设置,这样整个app都会生效,相关的代码与效果图如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//1.设置导航栏背景颜色
[[uinavigationbar appearance] setbartintcolor:[uicolor orangecolor]];
//2.设置导航栏背景图片
[[uinavigationbar appearance] setbackgroundimage:[uiimage imagenamed:@ "navigationbarimg" ] forbarmetrics:uibarmetricsdefault];
//3.设置导航栏标题样式
[[uinavigationbar appearance] settitletextattributes: [nsdictionary dictionarywithobjectsandkeys:
[uicolor purplecolor], nsforegroundcolorattributename,
[uifont boldsystemfontofsize:25], nsfontattributename, nil]];
//4.设置导航栏返回按钮的颜色
[[uinavigationbar appearance] settintcolor:[uicolor greencolor]];
//5.设置导航栏隐藏
[[uinavigationbar appearance] sethidden:yes];
|
设置导航栏样式效果图
2.局部设置:
全局设置后,如果只有其中几个页面导航栏样式不同,那么我们可以使用局部设置。
注意1:局部设置与全局设置方法相同,但调用方法的对象变成了"self.navigationcontroller.navigationbar"
注意2:局部设置必须遵循一个原则:"进入页面时修改,离开页面时还原”。
比如我们进入一个页面,需要设置当前导航栏的背景色为灰色,使用如下方法:
1
2
3
4
5
6
7
8
9
10
11
|
//进入页面时设置颜色:灰色
- ( void )viewwillappear:( bool )animated{
[super viewwillappear:animated];
[self.navigationcontroller.navigationbar setbartintcolor:[uicolor graycolor]];
}
//离开页面时还原为全局设置:橙色
- ( void )viewwilldisappear:( bool )animated{
[super viewwilldisappear:animated];
[self.navigationcontroller.navigationbar setbartintcolor:[uicolor orangecolor]];
}
|
二、解决自定义导航栏返回按钮后侧滑不可用问题
ios导航栏自带的返回按钮形式单一,所以大多情况下,我们都需要自定义导航栏返回按钮。但是此时我们却发现页面的侧滑返回功能不可用了。为了解决这个问题,我们需要在app中使用我们自定义的导航控制控制器,示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#import “basenavigationcontroller.h"
//第一步:设置自定义导航控制器使用uigesturerecognizerdelegate
@interface basenavigationcontroller ()<uigesturerecognizerdelegate>
@end
@implementation basenavigationcontroller
- ( void )viewdidload {
[super viewdidload];
//第二步:设置自定义导航控制器的侧滑手势的代理
self.interactivepopgesturerecognizer.delegate = self;
}
//第三步:实现代理方法
- ( bool )gesturerecognizershouldbegin:(uigesturerecognizer *)gesturerecognizer{
if (self.childviewcontrollers.count == 1) {
// 表示用户在根控制器界面,就不需要触发滑动手势,
return no;
}
return yes;
}
@end
|
三、隐藏导航栏底部的分割线
隐藏导航底部分割线也是我们偶尔会遇到的开发需求,首先我们可以通过xcode的debug view hierarchy功能查看导航栏的视图结构,效果如下:
导航栏视图层级图
从图中可以看出,导航栏的底部分割线是一个uiimageview对象,而且高度只有0.5,所以我们可以据此获取到导航栏的底部分割线对象,在一个视图控制器中实现此需求,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#import "testviewcontroller.h"
@interface testviewcontroller ()
//第一步:设置一个属性,存放导航栏底部分割线对象
@property (nonatomic, strong) uiimageview *navbarbottomimage;
@end
@implementation testviewcontroller
- ( void )viewdidload {
[super viewdidload];
////第三步:获取导航栏底部分割线对象
uiimageview *navbarbottomimage = [self findnavbarbottomimage:self.navigationcontroller.navigationbar];
self.navbarbottomimage = navbarbottomimage;
}
//第四步:设置分割线的显示或隐藏
//进入页面隐藏分割线
- ( void )viewwillappear:( bool )animated{
[super viewwillappear:animated];
self.navbarbottomimage.hidden = yes;
}
//离开页面时显示分割线
-( void )viewwilldisappear:( bool )animated{
[super viewwilldisappear:animated];
self.navbarbottomimage.hidden = no;
}
//第二步:添加用于获取导航栏分割线的方法
//导航栏底部分割线是一个uiimageview,且高度不超过1.0个高度,可据此查找此对象
-(uiimageview *)findnavbarbottomimage:(uiview *)view {
if ([view iskindofclass:uiimageview. class ] && view.bounds.size.height <= 1.0) {
return (uiimageview *)view;
}
for (uiview *subview in view.subviews) {
uiimageview *imageview = [self findnavbarbottomimage:subview];
if (imageview) {
return imageview;
}
}
return nil;
}
|
四、导航栏引起的布局问题
1.内容偏移属性:automaticallyadjustsscrollviewinsets
automaticallyadjustsscrollviewinsets是视图控制器的一个属性,默认为yes,用于优化滑动类视图(继承于uiscrollview的视图)在视图控制里的显示:
ios系统的导航栏uinavigationbar与标签栏uitabbar默认都是半透明模糊效果,在这种情况下系统会对视图控制器的ui布局进行优化:视图控制器里面第一个被添加进去的视图是滑动类视图,并且其frame是整个屏幕大小时,系统会自动调整其conteninset,以保证滑动视图里的内容不被uinavigationbar与uitabbar遮挡。
但是对于普通的视图,此时我们仍然需要注意:非滑动视图的布局仍然要考虑导航栏和标签栏高度,注意不被遮挡,比如布局的时候加上导航栏高度,以免内容被导航栏遮挡。
我们可以通过一段代码来测试一下效果,在默认导航栏(半透明)的视图控制器里添加如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//uitextview是滑动视图,内容自动向下偏移,不会被导航栏覆盖
uitextview *lefttextview = [[uitextview alloc] init];
lefttextview.frame = cgrectmake(0, 0,100, kdeviceheight); //
lefttextview.backgroundcolor = [uicolor lightgraycolor];
lefttextview.text = @ "君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪。人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。" ;
lefttextview.font = [uifont systemfontofsize:18];
lefttextview.editable = no;
[self.view addsubview:lefttextview];
//uiview是非滑动视图,内容被导航栏部分覆盖
uiview *rightview= [[uiview alloc] initwithframe:cgrectmake(150, 0, 100, 100)];
rightview.backgroundcolor = [uicolor redcolor];
[self.view addsubview:rightview];
|
导航栏透明情况下,滑动视图自动偏移,普通视图被遮挡
其实,这种系统的优化也是可以控制关闭的,关闭优化之后,滑动视图就会和普通视图一样,如果还设置其布局的原点是(0,0),其内容就会被导航栏所覆盖,关键代码如下:
1
2
3
4
5
6
7
|
//automaticallyadjustsscrollviewinsets在11.0后失效,所以需要判断
if (@available(ios 11.0,*)) {
scrollview.contentinsetadjustmentbehavior = uiscrollviewcontentinsetadjustmentnever;
} else {
//automaticallyadjustsscrollviewin,关闭自动偏移的系统优化
self.automaticallyadjustsscrollviewinsets = no;
}
|
2.边缘延伸属性:edgesforextendedlayout
edgesforextendedlayout也是视图控制器的布局属性,默认值是uirectedgeall,即:当前视图控制器里各种ui控件会忽略导航栏和标签的存在,布局时若设置其原点设置为(0,0),视图会延伸显示到导航栏的下面被覆盖。
所以我们可以设置self.edgesforextendedlayout=uirectedgenone
,此时视图控制器里内容就会避开导航栏和标签栏了,依然是上面的lefttextview和rightview,设置了uirectedgenone之后的效果图如下:
self.edgesforextendedlayout=uirectedgenone
3.导航栏透明属性translucent
上述两种属性都是在解决导航栏半透明情况下的布局问题,但是如果我们的需求就是导航栏不透明,那么视图控制器里的控件就会默认从(0,64)开始布局了,设置导航栏不透明的方法如下:
1
|
self.navigationcontroller.navigationbar.translucent= no;
|
相关文章:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://www.jianshu.com/p/50cd38f2772c