当前位置:   article > 正文

iOS 导航栏控制器UINavigationController 、UINavigationBar、UINavigationItem 之间的关系(一)_uinavigationcontroller和uinavigationbar的区别

uinavigationcontroller和uinavigationbar的区别

1、UINavigationController是一个容器,里面可以放很多的UIViewController(遵循先进后出的栈管理原则),那么来管理这些视图控制器(UIViewController)就是UINavigationBar,UINavigationBar是属于NavigationController的,只有一个,因此当你修改了UINavigationBar的某些属性时,是针对所有存放在UINavigationController里面的所有UIViewController。

2、UINavigationController会为每个入栈的UIViewController生成一个UINavigationItem,那么在某个UIViewController中通过修改UINavigationItem的某些属性,只针对当前的UIViewController。

简而言之:你要是改了UINavigationBar的属性,那影响就是全局的
修改UINavigationItem的属性,那影响就是局部的,只是当前页面受影响

(一)UINavigationBar相关属性

一、相关风格设置
1、样式

@property(nonatomic,assign) UIBarStyle barStyle 
//barStyle是一个枚举值,有些属性已经废弃了
typedef NS_ENUM(NSInteger, UIBarStyle) {
    UIBarStyleDefault          = 0,//白色
    UIBarStyleBlack            = 1,//黑色

    UIBarStyleBlackOpaque      = 1, // Deprecated. Use UIBarStyleBlack
    UIBarStyleBlackTranslucent = 2, // Deprecated. Use UIBarStyleBlack and set the translucent property to YES
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2、是否半透明

//导航栏中有个重要的属性:translucent(半透明),在ios7之后默认值是YES,之前是NO。
@property(nonatomic,assign,getter=isTranslucent) BOOL translucent
  • 1
  • 2

3、自定义背景图像和导航栏底部的阴影

/*
设置背景图片,注意背景图片的透明度及translucent属性相结合,展示效果
手机横屏、竖屏的样式
typedef NS_ENUM(NSInteger, UIBarMetrics) {
     UIBarMetricsDefault,//正常竖屏状态
     UIBarMetricsCompact,//横屏状态
     };
     */
*/
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics 
- 
//该属性导航栏的阴影image(shadowImage),必须与setBackgroundImage:forBarMetrics 一起设置,单独设置shadowImage不会显示
@property(nullable, nonatomic,strong) UIImage *shadowImage
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4、设置导航栏的背景颜色

@property(nullable, nonatomic,strong) UIColor *barTintColor
  • 1

5、返回按钮及返回按钮旁边字体的颜色

@property(null_resettable, nonatomic,strong) UIColor *tintColor
  • 1

6、导航栏的标题属性等设置

@property(nullable,nonatomic,copy) NSDictionary<NSString *,id> *titleTextAttributes
//标题在竖直位置的偏移,即可向上或者向下移动
- (void)setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics

//[nav setTitleVerticalPositionAdjustment:10 forBarMetrics:UIBarMetricsDefault];向下偏移10px
  • 1
  • 2
  • 3
  • 4
  • 5

7、修改默认返回按钮的图片设置

//这两个属性需要一起设置,否则无效
@property(nullable,nonatomic,strong) UIImage *backIndicatorImage;
@property(nullable,nonatomic,strong) UIImage *backIndicatorTransitionMaskImage;
  • 1
  • 2
  • 3

A、我们先来看下上面几个属性不同设置,相结合的展示效果
1)、设置导航栏样式barStyle
2)、半透明属性translucent
3)、导航栏背景颜色barTintColor
4)、自定义导航栏背景图片
5)、导航栏阴影

我们看下我们选择的导航栏背景图
这里写图片描述

- (void)initNavBarColorAndTranslucentAndTranslucentBg{

    UINavigationBar *nav = [UINavigationBar appearance];

    nav.barStyle =  UIBarStyleBlack;//UIBarStyleDefault
    nav.translucent = NO;//设置不透明,ios7以后默认yes,之前默认no
    nav.barTintColor = [UIColor orangeColor];//设置导航栏的背景色
    //此处的导航栏背景图示一个透明度为60%
    [nav setBackgroundImage:[UIImage imageNamed:@"navBgTranslucent"] forBarMetrics:UIBarMetricsDefault];
    nav.shadowImage = [UIImage imageNamed:@"show"];
    nav.tintColor = [UIColor orangeColor];
    nav.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor cyanColor]};

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

然后相关属性结合的展示效果图

这里写图片描述

结果导航条展示的颜色跟原先的不一样了,为啥呢?我们看到文档中对于translucent属性说明中有提到

 If you send setTranslucent:NO to a bar with a translucent custom background image
 it will provide an opaque background for the image using the bar's barTintColor if defined, or black
 for UIBarStyleBlack or white for UIBarStyleDefault if barTintColor is nil.
 //自定义图片的alpha < 1  && translucent = NO, 它将使用bar的barTintColor(如果定义)或黑色为图像提供不透明的背景
   对于UIBarStyleBlack,如果barTintColor为零,则为UIBarStyleDefault。
  • 1
  • 2
  • 3
  • 4
  • 5

即我们此处的:自定义图片的alpha < 1 && translucent = NO, barTintColor = orangeColor,则用barTintColor来填充导航栏的背景

B、我们只将A的nav.barTintColor的属性去掉,即如下代码

//设置Bar颜色,半透明属性,半透明的背景图
- (void)initNavBarStyleAndTranslucentAndTranslucentBg{

    UINavigationBar *nav = [UINavigationBar appearance];
    nav.barStyle =  UIBarStyleBlack;
    nav.translucent = NO;//设置不透明,ios7以后默认yes,之前默认no

    [nav setBackgroundImage:[UIImage imageNamed:@"navBgTranslucent"] forBarMetrics:UIBarMetricsDefault];
    nav.shadowImage = [UIImage imageNamed:@"show"];
    nav.tintColor = [UIColor orangeColor];
    nav.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor cyanColor]};

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这里写图片描述

自定义图片的alpha < 1 && translucent = NO, 没有设置barColor,黑色填充

C、我们将A的nav.barTintColor的属性和barStyle = UIBarStyleDefault去掉,即如下代码

- (void)initNavBarStyleAndTranslucentAndTranslucentBg{

    UINavigationBar *nav = [UINavigationBar appearance];

    nav.barStyle =  UIBarStyleDefault;//UIBarStyleDefault
    nav.translucent = NO;//设置不透明,ios7以后默认yes,之前默认no

    [nav setBackgroundImage:[UIImage imageNamed:@"navBgTranslucent"] forBarMetrics:UIBarMetricsDefault];
    nav.shadowImage = [UIImage imageNamed:@"show"];
    nav.tintColor = [UIColor orangeColor];
    nav.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor cyanColor]};

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这里写图片描述

自定义图片的alpha < 1 && translucent = NO, 没有设置barColor,白色填充

上面的A、B、C中,若是将nav.translucent 属性不设置,即默认为YES,半透明。那么上面的上面的3种都会是如下效果

这里写图片描述

即原先设置的barColor和barStyle等都会失效

D、我们看下自定义背景图片的aplha = 1 即不透明
这里写图片描述

对于背景图片我们选择alpha = 1,即不透明。不设置translucent,则会自己推断出translucent = NO,虽然不设置该属性的话默认值是YES,但是对于这种情况下则是不透明

- (void)initNavTrueBg{

    UINavigationBar *nav = [UINavigationBar appearance];

    nav.barStyle =  UIBarStyleBlack;//UIBarStyleDefault
    [nav setBackgroundImage:[UIImage imageNamed:@"navBg"] forBarMetrics:UIBarMetricsDefault];
    nav.shadowImage = [UIImage imageNamed:@"show"];
    nav.tintColor = [UIColor whiteColor];
    nav.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor cyanColor]};

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里写图片描述

E、对于D情况,我们在代码中设置translucent = yes,则会出现如下情况

这里写图片描述

对于以上各种情况,我们不难发现,只要UINavigationBar的translucent的值时YES,那么view的fream从顶部开始,否则从导航栏下面开始。对于不透明的自定义图片来说,translucent的值要是不设置,就会有蒙层。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/219325
推荐阅读
相关标签
  

闽ICP备14008679号