我们可以做个总结,必威:通过颜色、通过图片

navigationBar设置背景有二种艺术:通过颜色、通过图片


1.为啥要聊聊UINavigationBar?

在做项目时,相比较蛋疼的正是晶莹导航栏和非透明导航栏的切换难题,特别是在侧滑重返时,上二个页面能够透过导航栏看到下一个页面,形成很意外的体现。所以,因为踩坑太多,需求明白一下,导航栏到底是个什么东东。(PS: 这么些主题素材其实如若当前页面包车型客车view充满整个显示器,就不能够由此导航栏看见下贰个页面了。)

核心介绍
  • UIBarItem二个得以停放在Bar之上的全体小控件类的抽象类,能够设置标题,图片等
  • UIBarButtonItem承继UIBarItem,扩展了动作以及指标等button的习性。也正是放在UIToolBar或然UINavigationBar上的独特的button。
  • UINavigationItem满含了title,prompt,titleView,leftBarButtonItem,rightBarButtonItem,backBarButonItem等近来页面上具有的新闻
  • UINavigationBarNavigaitonBar正是导航栏 主要对UINavigationItem进行栈管理 显示导航栏的外观背景
  • UINavigationController包含了viewcontrollers、navigationbar、toolbar

2.translucent  (暗中认可是YES  iOS7油但是生的 设置导航条是不是透明)

有设置自定义背景图时只怕出现的意况

1)暗中认可依附图来设置是或不是透明,当图上若是有大肆像素是阿尔法小于1,就YES

2)设置的背景是不透明的图片,也能透过安装translucent 为YES,系统会使用一张opacity值小于1的图

3)设置的背景是晶莹剔透的图纸,设置translucent为NO,系统会使用一张不透明的背景图

透过图形设置

有成都百货上千眼花缭乱的背景观提议利用图片来做setBackgroundImage: forBarMetrics: 支持iOS5及以上

要么婴儿听话,同有时候用-setBackgroundImage:forBarMetrics:方法设置背景颜色。

3.推荐介绍管理导航栏相比好用的第三方库

  • WRNavigationBar

W汉兰达NavigationBar达成的法规是,把系统的backgroundImage设置为透明,然后自个儿在backgroundView加多背景,设置图片背景的时候加多imageView,设置颜色背景时,直接增添view设置背景颜色,透明则透过直接设置backgroundView的阿尔法值来展现。而底部的影子分界线只是提供了掩盖和显示的办法,也是透过直接遮盖shadowImage来完结的,焦点代码如下:

@implementation UINavigationBar (WRAddition)

// set navigationBar backgroundImage
- (void)wr_setBackgroundImage:(UIImage *)image
{
    [self.backgroundView removeFromSuperview];
    self.backgroundView = nil;
    if (self.backgroundImageView == nil)
    {
        // add a image(nil color) to _UIBarBackground make it clear
        [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        self.backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), kWRNavBarBottom)];
        // _UIBarBackground is first subView for navigationBar
        [self.subviews.firstObject insertSubview:self.backgroundImageView atIndex:0];
    }
    self.backgroundImageView.image = image;
}

// set navigationBar barTintColor
- (void)wr_setBackgroundColor:(UIColor *)color
{
    [self.backgroundImageView removeFromSuperview];
    self.backgroundImageView = nil;
    if (self.backgroundView == nil)
    {
        // add a image(nil color) to _UIBarBackground make it clear
        [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
        self.backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), kWRNavBarBottom)];
        // _UIBarBackground is first subView for navigationBar
        [self.subviews.firstObject insertSubview:self.backgroundView atIndex:0];
    }
    self.backgroundView.backgroundColor = color;
}

// set _UIBarBackground alpha (_UIBarBackground subviews alpha <= _UIBarBackground alpha)
- (void)wr_setBackgroundAlpha:(CGFloat)alpha
{
    UIView *barBackgroundView = self.subviews.firstObject;
    barBackgroundView.alpha = alpha;
}

  • KMNavigationBarTransition

KMNavigationBarTransition完结的原理分解:
KMNavigationBarTransition主要的文书是四个category,分别是UINavigationController+KMNavigationBarTransitionUIViewController+KMNavigationBarTransition,其中UINavigationController+KMNavigationBarTransitionhook多少个艺术:

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        KMSwizzleMethod([self class],
                        @selector(pushViewController:animated:),
                        @selector(km_pushViewController:animated:));

        KMSwizzleMethod([self class],
                        @selector(popViewControllerAnimated:),
                        @selector(km_popViewControllerAnimated:));

        KMSwizzleMethod([self class],
                        @selector(popToViewController:animated:),
                        @selector(km_popToViewController:animated:));

        KMSwizzleMethod([self class],
                        @selector(popToRootViewControllerAnimated:),
                        @selector(km_popToRootViewControllerAnimated:));

        KMSwizzleMethod([self class],
                        @selector(setViewControllers:animated:),
                        @selector(km_setViewControllers:animated:));
    });
}

UIViewController+KMNavigationBarTransitionhook了四个方法:

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        KMSwizzleMethod([self class],
                        @selector(viewWillLayoutSubviews),
                        @selector(km_viewWillLayoutSubviews));

        KMSwizzleMethod([self class],
                        @selector(viewDidAppear:),
                        @selector(km_viewDidAppear:));
    });
}

以push为例,KMNavigationBarTransition在km_pushViewController:animated:方式里做了以下操作:

- (void)km_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    UIViewController *disappearingViewController = self.viewControllers.lastObject;
    if (!disappearingViewController) {
        return [self km_pushViewController:viewController animated:animated];
    }
    if (!self.km_transitionContextToViewController || !disappearingViewController.km_transitionNavigationBar) {
    [disappearingViewController km_addTransitionNavigationBarIfNeeded];
    }
    if (animated) {
        self.km_transitionContextToViewController = viewController;
        if (disappearingViewController.km_transitionNavigationBar) {
            disappearingViewController.km_prefersNavigationBarBackgroundViewHidden = YES;
        }
    }
    return [self km_pushViewController:viewController animated:animated];
}

在就要消失的controller,也正是push的上八个controller增多了三个navigationBar,况兼将系统的navigationBarBackground隐蔽:

- (void)km_addTransitionNavigationBarIfNeeded {
    if (!self.isViewLoaded || !self.view.window) {
        return;
    }
    if (!self.navigationController.navigationBar) {
        return;
    }
    [self km_adjustScrollViewContentOffsetIfNeeded];
    UINavigationBar *bar = [[UINavigationBar alloc] init];
    bar.barStyle = self.navigationController.navigationBar.barStyle;
    if (bar.translucent != self.navigationController.navigationBar.translucent) {
        bar.translucent = self.navigationController.navigationBar.translucent;
    }
    bar.barTintColor = self.navigationController.navigationBar.barTintColor;
    [bar setBackgroundImage:[self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault];
    bar.shadowImage = self.navigationController.navigationBar.shadowImage;
    [self.km_transitionNavigationBar removeFromSuperview];
    self.km_transitionNavigationBar = bar;
    [self km_resizeTransitionNavigationBarFrame];
    if (!self.navigationController.navigationBarHidden && !self.navigationController.navigationBar.hidden) {
        [self.view addSubview:self.km_transitionNavigationBar];
    }
}

viewWillLayoutSubviews方法里做了相同的操作,把将在push的controller增添navigationBar,然后掩盖系统的navigationBarBackground:

- (void)km_viewWillLayoutSubviews {
    id<UIViewControllerTransitionCoordinator> tc = self.transitionCoordinator;
    UIViewController *fromViewController = [tc viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [tc viewControllerForKey:UITransitionContextToViewControllerKey];

    if ([self isEqual:self.navigationController.viewControllers.lastObject] && [toViewController isEqual:self] && self.navigationController.km_transitionContextToViewController) {
        if (self.navigationController.navigationBar.translucent) {
            [tc containerView].backgroundColor = [self.navigationController km_containerViewBackgroundColor];
        }
        fromViewController.view.clipsToBounds = NO;
        toViewController.view.clipsToBounds = NO;
        if (!self.km_transitionNavigationBar) {
            [self km_addTransitionNavigationBarIfNeeded];

            self.km_prefersNavigationBarBackgroundViewHidden = YES;
        }
        [self km_resizeTransitionNavigationBarFrame];
    }
    if (self.km_transitionNavigationBar) {
        [self.view bringSubviewToFront:self.km_transitionNavigationBar];
    }
    [self km_viewWillLayoutSubviews];
}

viewDidAppear个校官本人加上的navigationBar移除,展现系统的navigationBar:

- (void)km_viewDidAppear:(BOOL)animated {
    if (self.km_transitionNavigationBar) {
        self.navigationController.navigationBar.barTintColor = self.km_transitionNavigationBar.barTintColor;
        [self.navigationController.navigationBar setBackgroundImage:[self.km_transitionNavigationBar backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault];
        [self.navigationController.navigationBar setShadowImage:self.km_transitionNavigationBar.shadowImage];

        UIViewController *transitionViewController = self.navigationController.km_transitionContextToViewController;
        if (!transitionViewController || [transitionViewController isEqual:self]) {
            [self.km_transitionNavigationBar removeFromSuperview];
            self.km_transitionNavigationBar = nil;
            self.navigationController.km_transitionContextToViewController = nil;
        }
    }
    self.km_prefersNavigationBarBackgroundViewHidden = NO;
    [self km_viewDidAppear:animated];
}

完全流程便是,先加多自定义的navigationBar,隐蔽系统的navigationBar,等push实现就移除自定义的navigationBar,显示系统的navigationBar。

2.UINavigationItem

NS_CLASS_AVAILABLE_IOS @interface UINavigationItem : NSObject <NSCoding>//初始化- (instancetype)initWithTitle:(NSString *)title NS_DESIGNATED_INITIALIZER;- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;//设置导航栏中间的内容标题@property(nullable, nonatomic,copy) NSString *title; //设置导航栏中间的内容视图 @property(nullable, nonatomic,strong) UIView *titleView; //提示@property(nullable,nonatomic,copy) NSString *prompt; //返回@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem; //是否隐藏返回Button@property(nonatomic,assign) BOOL hidesBackButton;- setHidesBackButton:hidesBackButton animated:animated;//左边数组Item@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *leftBarButtonItems NS_AVAILABLE_IOS;//右边数组Item@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems NS_AVAILABLE_IOS;- setLeftBarButtonItems:(nullable NSArray<UIBarButtonItem *> *)items animated:animated NS_AVAILABLE_IOS;- setRightBarButtonItems:(nullable NSArray<UIBarButtonItem *> *)items animated:animated NS_AVAILABLE_IOS;//通过指定该属性为YES,可以让leftBarButtonItem和backBarButtonItem同时显示,其中leftBarButtonItem显示在backBarButtonItem的右边 默认值为NO@property(nonatomic) BOOL leftItemsSupplementBackButton NS_AVAILABLE_IOS;//左边Item@property(nullable, nonatomic,strong) UIBarButtonItem *leftBarButtonItem;//右边Item@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;- setLeftBarButtonItem:(nullable UIBarButtonItem *)item animated:animated;- setRightBarButtonItem:(nullable UIBarButtonItem *)item animated:animated;@end

prompt 是一个NSString类型描述,注意增加该描述未来NavigationBar的万丈会大增30,总的中度会化为74(不管当前来头是Portrait依旧Landscape,此方式下navgationbar都应用中度44丰裕prompt30的艺术开展呈现)。

如:

self.navigationItem.prompt=@"这是什么?";self.title=@"HAH";

必威 1prompt.png

3.颜色,背景图 (一般是安装了背景图,设置的颜色就能被遮掉,透明的图纸会流露底色,注意层级关系)

self.navigationController.navigationBar.backgroundColor = [UIColor redColor];    //UINavigationBar

self.navigationController.navigationBar.barTintColor = [UIColor cyanColor];      //_UIBarBackground                  已屏弃的tintColor

[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"custom_navBar_opaque"] forBarMetrics:UIBarMetricsDefault]; //UIImageView

self.navigationController.navigationBar.translucent = NO;

必威 2

self.navigationController.navigationBar.translucent = NO;

必威 3

当未有设置背景图片的时候 

必威 4

有设置背景图片

必威 5

经过颜色设置

tintColor:iOS7在此之前就不能改造背景颜色barTintColor:iOS7及随后选拔还应该有一种说法是tintColor能够改换baritem的颜料,今后有空子验证下

暗中同意有一条线,去掉方法:

self.navigationBar.shadowImage = [UIImage new];

修改章程:

self.navigationBar.shadowImage = [UIImage imageNamed:@"navigationBarShadowImage"];

大致意思,你如若要通过设置这几个性格来修改分水线,那么你要同时通过setBackgroundImage:forBarMetrics:为UINavigationBar设置一个背景图片,那样您设置的分水线样式技巧奏效。一发轫自己是不信的,那我们来试一下。

UINavigationBar是苹果系统自带的,一个很方便使用的导航栏,而且在同贰个UINavigationController的调节器栈里面,分享三个UINavigationBar,能够保持统一性,可是,也因为是集体叁个UINavigationBar,所以,只要决定器栈里面包车型地铁某贰个调控器修改了UINavigationBar会影响全体的调整器,那也算四个破绽。

@interface UINavigationController : UIViewController@property(nonatomic,readonly) UINavigationBar *navigationBar;@interface UIViewController (UINavigationControllerItem)@property(nonatomic,readonly,strong) UINavigationItem *navigationItem;@interface UINavigationBar : UIView@property(nullable, nonatomic,readonly,strong) UINavigationItem *topItem;@property(nullable, nonatomic,readonly,strong) UINavigationItem *backItem;@property(nullable,nonatomic,copy) NSArray<UINavigationItem *> *items;@interface UINavigationItem : NSObject@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *leftBarButtonItems;@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems;@property(nullable, nonatomic,strong) UIBarButtonItem *leftBarButtonItem;@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;@interface UIBarButtonItem : UIBarItem@property(nullable, nonatomic) SEL action; @interface UIBarItem : NSObject@property(nullable, nonatomic,copy) NSString *title;@property(nullable, nonatomic,strong) UIImage *image;

6.1   UIBarButtonItem : UIBarItem (导航栏上的按键,类似UIButton)

@property(nonatomic)        UIBarButtonItemStyle style;            // default is UIBarButtonItemStylePlain

@property(nullable, nonatomic,strong)  __kindof UIView    *customView;      // default is nil

@property(nullable, nonatomic)        SEL                  action;          // default is NULL

@property(nullable, nonatomic,weak)    id                  target;          // default is nil

shadowImage修改不见效原因

当navigationBar的背景是经过颜色设置的时候,对于shadowImage的修改是不奏效的,独有当通过图片设置的时候技能够修改

//获取荧屏高度

#define kWidth [UIScreen mainScreen].bounds.size.width

//获取状态栏中度

#define kStatus_h  [[UIApplication sharedApplication] statusBarFrame].size.height

2.先来解剖一下UINavigationBar的层级

此地只涉及到iOS8~iOS10,由于尚未iOS8之下的模拟器,也未曾真机(),并且将来大多手提式有线话机系统都在iOS8之上了,iOS11也只是测量检验版,不稳固,先不管。下边步向正题:(PS: 上面皆以居于三星6)

必威 6

UINavigationBar层级.png

(1)iOS8/iOS9中UINavigationBar的层级结构如下:

UINavigationBar
    —— _UINavigationBarBackground
            —— _UIBackdropView  
            —— _UIBackdropEffectView
            —— UIImageView
    —— UINavigationItemView
    —— UINavigationButton
    —— _UINavigationBarBackIndicatorView

看一下那都以如何类???

UINavigationBar->UIView 
frame = (0 20; 375 44); opaque = NO; autoresize = W

_UINavigationBarBackground->_UIBarBackgroundImageView->UIImageViewframe = (0 -20; 375 64); autoresize = W; userInteractionEnabled = NO

_UIBackdropView->UIView 
frame = (0 0; 375 64); opaque = NO; autoresize = W+H; userInteractionEnabled = NO

_UIBackdropEffectView->UIView 
frame = (0 0; 375 64); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO

UIImageView->UIView 
frame = (0 64; 375 0.5); userInteractionEnabled = NO 

UINavigationItemView->UIView
frame = (170.5 8; 34 27); opaque = NO; userInteractionEnabled = NO

UINavigationButton->UIButton->UIControl->UIView
frame = (316 7; 51 30); opaque = NO

_UINavigationBarBackIndicatorView->UIImageView
frame = (8 11.5; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO

地方能够吸收几点:
1. UINavigationBar的frame是(0 20; 375 44),所以UINavigationBar和UIStatusBar并不是混在一起的。
2. _UINavigationBarBackground的frame是(0 -20; 375 64),并且是UIImageView类型,也就是我们改变导航栏的背景图片就是赋值给这个类。
3. UIImageView,不用多说,这个就是阴影图片,它的frame是(0 64; 375 0.5),从64开始算,也就是说,将UINavigationBar的clipToBounds=Yes就能屏蔽掉底部阴影线。
4. 导航栏的背景 _UINavigationBarBackground,标题UINavigationItemView,左右按钮UINavigationButton和返回图片_UINavigationBarBackIndicatorView都是在同一层级。
5. _UIBackdropView和_UIBackdropEffectView是给导航栏添加上毛玻璃效果的类。

(2)iOS10中UINavigationBar的层级结构如下:

UINavigationBar
    —— _UIBarBackground
            —— UIImageView
            —— UIVisualEffectView
            —— _UIVisualEffectBackdropView
            —— _UIVisualEffectFilterView
    —— UINavigationItemView
    —— UINavigationButton
    —— _UINavigationBarBackIndicatorView

iOS第10中学的导航栏和iOS8/iOS9的导航栏层级结构基本上,分化在于应用系统提供的毛玻璃类:

UIVisualEffectView->UIView
frame = (0 0; 375 64)

_UIVisualEffectBackdropView->_UIVisualEffectSubview->UIView
frame = (0 0; 375 64); autoresize = W+H; userInteractionEnabled = NO

_UIVisualEffectFilterView->_UIVisualEffectSubview->UIView
frame = (0 0; 375 64); autoresize = W+H; userInteractionEnabled = NO

3.自定义导航栏的归来按钮

@property(nonatomic,readonly) UINavigationBar *navigationBar;// The navigation bar managed by the controller. Pushing, popping or setting navigation items on a managed navigation bar is not supported.

受controller管理的navigationBar 不协理对navigation items操作,所以这里对回到开关的操作是在ViewController完毕的,以下代码中self表示ViewController

Apple官方对setBackIndicatorImage和setBackIndicatorTransitionMaskImage做了之类解释,必需同期设置本领见效

/* The back indicator image is shown beside the back button. The back indicator transition mask image is used as a mask for content during push and pop transitions Note: These properties must both be set if you want to customize the back indicator image. */

1.自定义文字+图片

-createCustomBackBarItem { //修改图片文字颜色 self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; //替换图片 [self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"erwema"]]; [self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"erwema"]]; //设置文字 UIBarButtonItem * backBarItem = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil]; self.navigationItem.backBarButtonItem = backBarItem;}

瞩目:对backBarButtonItem的更换是在时下viewController前二个页面达成的,在此时此刻页面修改针对下贰个viewController的navigationItem生效

2.不显得文字设置Title在Y方向上的偏移量,使其移除荧屏,该方法在首先次步入时会有个文字移动的卡通效果,效果倒霉,不引入应用

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake forBarMetrics:UIBarMetricsDefault];

3.用到leftBarButtonItem取代backBarButtonItem使用这种方法,不能够采纳边缘滑动返反击势,且不能够并且安装图片和标题

-setLeftBarItemBack{ UIBarButtonItem *leftBarBtnItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:self action:@selector(clickLeftBarBtnItem:)]; [self.navigationItem setLeftBarButtonItem:leftBarBtnItem animated:YES]; self.navigationItem.leftBarButtonItem.tintColor = NavigationLeftBackColor;}/** * 导航条leftBarBtn事件 */- clickLeftBarBtnItem:(UIBarButtonItem *)sender { [self.navigationController popViewControllerAnimated:YES];}

4.采取CustomView的秘技此措施不适于backBarButtonItem,只好用于leftBarButtonItem

小心:1.倘使B视图有二个自定义的侧面按键(leftBarButtonItem),则会显示那几个自定义开关;2.万一B未有自定义按键,不过A视图的backBarButtonItem属性有自定义项,则呈现这些自定义项;3.一旦前2条都并未有,则私下认可展现贰个向下按钮,后退按键的题目是A视图的标题;

这里注意:5.0中新追加了二个属性leftItemsSupplementBackButton,通过点名该属性为YES,能够让leftBarButtonItem和backBarButtonItem同临时候展现,个中leftBarButtonItem展现在backBarButtonItem的左边。

选取3、4办法,边缘再次来到会失效,此时增加那句代码如故得以兑现边缘滑动重返

 self.navigationController.interactivePopGestureRecognizer.delegate = self;

这里推荐使用FDFullscreenPopGesture 全屏滑动手势再次来到,降低专业量。

UINavigationBar 承袭于UIView 最佳幸免直接在上头加多分界面成分,在push pop 中,系统不会管理,会间接存在。必要在viewWillAppear viewWillDisappear增多删除 

//通过安装逼arTintColor为 navigationBar设置背景颜色

[self.navigationController.navigationBar setBarTintColor:[UIColor whiteColor]];

//通过-setBackgroundImage:forBarMetrics:方法设置杏黄背景颜色

UIImage *bgimage = [UIImage imageFromColor:[UIColor whiteColor] withSize:CGSizeMake(kWidth, kStatus_h + 44.f)];

[self.navigationController.navigationBar setBackgroundImage:bgimage forBarMetrics:UIBarMetricsDefault];

总结:

navigationBar是贰个令人又爱又恨的事物,但是知情了navigationBar的层级关系,到时候,出了难点要么想要完毕部分系统未有的职能就便于的多了。并且,一些第三方库封装的很好,能够直接用,我们就绝不再一次造轮子了。

1.UINavigationBar的背景颜色

-changeNavigationBarBackgroundColor { //背景色 self.navigationBar.barTintColor = [UIColor blueColor]; //title字体 //[self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor lightGrayColor],NSFontAttributeName:[UIFont systemFontOfSize:17]}]; //修改UIBarButtonItem 图片 title颜色 self.navigationBar.tintColor = [UIColor greenColor]; //是否半透明 当为YES时 设置的导航栏背景颜色会和实际rgb值有误差 self.navigationBar.translucent = NO; //如果想要半透明效果 颜色没有色差 可以通过设置背景图片的方法 背景图片会覆盖barTintColor //- setBackgroundImage:(nullable UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics}

5.UINavigationBar暗许有八个UINavigationItem

@property(nullable, nonatomic,readonly,strong) UINavigationItem *topItem; 

@property(nullable, nonatomic,readonly,strong) UINavigationItem *backItem; //默许是空

必威 7

由此品种方法 self.navigationItem 得到的也是暗中认可的这几个

必威 8

4.UINavigationController

NS_CLASS_AVAILABLE_IOS @interface UINavigationController : UIViewController//UINavigationController初始化,自定义NavigationBar,自定义toolbar- (instancetype)initWithNavigationBarClass:(nullable Class)navigationBarClass toolbarClass:(nullable Class)toolbarClass NS_AVAILABLE_IOS;//UINavigationController初始化,导航控制器的根控制器- (instancetype)initWithRootViewController:(UIViewController *)rootViewController;//压栈:将目标控制器压入栈中- pushViewController:(UIViewController *)viewController animated:animated; //弹栈:将栈顶控制器从栈中弹出- (nullable UIViewController *)popViewControllerAnimated:animated;//弹栈:弹到指定的目标控制器- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:animated; //弹栈:弹到根控制器- (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:animated;//导航栈的栈顶视图 只读 就是某个导航栈的栈顶视图,和导航息息相关@property(nullable, nonatomic,readonly,strong) UIViewController *topViewController; //当前显示的控制器 只读 visibleViewController和哪个导航栈没有关系,只是当前显示的控制器,也就是说任意一个导航的visibleViewController所返回的值应该是一样的@property(nullable, nonatomic,readonly,strong) UIViewController *visibleViewController;//栈里的视图控制器数组@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;//替换栈中的视图控制器数组- setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:animated NS_AVAILABLE_IOS; //是否隐藏导航栏@property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;//设置导航栏隐藏 是否有动画- setNavigationBarHidden:hidden animated:animated; //导航栏@property(nonatomic,readonly) UINavigationBar *navigationBar; //toolbar是否隐藏@property(nonatomic,getter=isToolbarHidden) BOOL toolbarHidden NS_AVAILABLE_IOS;//toolbar是否隐藏 是否有动画- setToolbarHidden:hidden animated:animated NS_AVAILABLE_IOS; //toolbar对象@property(null_resettable,nonatomic,readonly) UIToolbar *toolbar NS_AVAILABLE_IOS; //委托@property(nullable, nonatomic, weak) id<UINavigationControllerDelegate> delegate;//边缘侧滑返回手势@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS;//展示视图控制器- showViewController:(UIViewController *)vc sender:(nullable id)sender NS_AVAILABLE_IOS; // Interpreted as pushViewController:animated://输入键盘出现时将导航栏隐藏 IOS8特性@property (nonatomic, readwrite, assign) BOOL hidesBarsWhenKeyboardAppears NS_AVAILABLE_IOS;//滚动页面时隐藏Bar IOS8特性@property (nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe NS_AVAILABLE_IOS;//获取能够隐藏navigationBar的滑动手势 只读@property (nonatomic, readonly, strong) UIPanGestureRecognizer *barHideOnSwipeGestureRecognizer NS_AVAILABLE_IOS;//当设置为true时,横向方向时隐藏NavigationBar@property (nonatomic, readwrite, assign) BOOL hidesBarsWhenVerticallyCompact NS_AVAILABLE_IOS;//当设置为true时,如果有没处理的点击手势就会隐藏和现实navigationBar @property (nonatomic, readwrite, assign) BOOL hidesBarsOnTap NS_AVAILABLE_IOS;//获取能够隐藏navigationBar的点击手势 只读@property (nonatomic, readonly, assign) UITapGestureRecognizer *barHideOnTapGestureRecognizer NS_AVAILABLE_IOS;@end

@interface UIViewController (UINavigationControllerItem)//导航栏上面用户自定义视图@property(nonatomic,readonly,strong) UINavigationItem *navigationItem; //推送时隐藏bottom@property(nonatomic) BOOL hidesBottomBarWhenPushed;//下级视图的导航控制器@property(nullable, nonatomic,readonly,strong) UINavigationController *navigationController; @end

@interface UIViewController (UINavigationControllerContextualToolbarItems)//属性设置工具条中包含的按钮@property (nullable, nonatomic, strong) NSArray<__kindof UIBarButtonItem *> *toolbarItems NS_AVAILABLE_IOS;- setToolbarItems:(nullable NSArray<UIBarButtonItem *> *)toolbarItems animated:animated NS_AVAILABLE_IOS;@end

6.UINavigationItem : NSObject  

title 

titleView

prompt

backBarButtonItem

leftBarButtonItems

rightBarButtonItems

笔者们设置的新民主主义革命分水线并从未立见功用,而是私下认可的紫铜色。

4.navigationBar偶然展现上贰个页面包车型大巴navigationBar

相似景色下都是平常的。不过在不常意况下,会产出在进入新分界面后,新分界面包车型地铁navigationBar会忽然未有,出现的依旧上一个分界面包车型大巴navigationBar。从此之后,navigationBar 全乱了, kill 掉重新进,复苏符合规律。原因:一般大家会打点调用navigationBarHidden的性质来设置导航栏是或不是隐身,这种办法是不拉动画效率的。那样有的时候候就能形成错乱,那应当是三个类别的bug,所以应竭尽使用

[self.navigationController setNavigationBarHidden:YES animated:YES];

来设置navigationBar的Hidden属性。

4.shadowImage 

(暗中认可是nil , 会展现暗中同意的一张shadow image)

当想用自定义的shadowImage替换暗中同意图片时,也要安装自定义背景图,否者依然是暗许阴影图片

必威 9

如上代码都以在iOS 10.3.1 上的模拟器运转。后来自身发觉,在iOS11和上述的配备上早已无需利用

提到综述
  • UINavigationController是叁个容器类,对ViewController进行栈管理,包涵navigationBar。
  • UINavigationBar 即UINavigationController顶上部分的导航栏,首要担任外观背景的显示,并对navigationItem实行栈管理
  • UINavigationItem是导航栏上出示的切实的成分的三个抽象类,UINavigationController 通过Category的办法为ViewController加多了五个navigationItem,把UINavigationItem交由ViewController管理

// Created on-demand so that a view controller may customize its navigation appearance.

这里引用叶落寒的一段介绍,更加的简单明了

伊始地说正是,UINavigationController是个容器,里面能够装比相当多UIViewController。装这么多UIViewController让客商怎么调控它们啊?总得有个工具吧,那些工具正是UINavigationBar。二个容器就像此三个bar,也就是决定台吧。不过管理那么多UIViewController,调控台上得按键啊、标题啊,都完全一样是还是不是看起来太鄙俗了。为了缓和那个主题材料,UINavigationController为每一个UIViewController生成二个UINavigationItem,通过那些UINavigationItem能够更换调节台“上边”的按键和标题。倘使您不自定义UINavigationItem,UINavigationController会使用暗许的;

6.2 UIBarItem : NSObject(类似UIView)

enabled

title

image

tag

imageInsets

landscapeImagePhoneInsets

- (void)setTitleTextAttributes:(nullable NSDictionary*)attributes forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

-

本文由必威发布于必威-编程,转载请注明出处:我们可以做个总结,必威:通过颜色、通过图片

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。