UINavigationController,UINavigationBar,UIBarButtonItem

1.UINavigationController继承自UIViewController

#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIViewController.h>
#import <UIKit/UIKitDefines.h>
#import <UIKit/UIInterface.h>
#import <UIKit/UIGeometry.h>
#import <UIKit/UIPanGestureRecognizer.h>
#import <UIKit/UITapGestureRecognizer.h>

UINavigationController管理堆栈视图控制器和一个导航栏。它执行水平视图转换为推动的导航栏和弹出视图,同时保持同步。大多数客户不需要子类UINavigationController。如果导航控制器是嵌套在tabbar控制器,它使用标题和底部的工具栏属性视图控制器在堆栈上。UINavigationController是可旋转的前视图控制器是否可旋转。导航控制器之间不均匀rotatability目前不支持。

UINavigationControllerOperation操作方式

UINavigationControllerOperationNone,---none
UINavigationControllerOperationPush,--push
 UINavigationControllerOperationPop,--pop

UINavigationControllerHideShowBarDuration---CGFloat

导航栏出现或者消失所用时间

导航控制器相关

@class UIView, UINavigationBar, UINavigationItem, UIToolbar;
@protocol UINavigationControllerDelegate;

导航控制器的方法

/* Use this initializer to make the navigation controller use your custom bar class.
Passing nil for navigationBarClass will get you UINavigationBar, nil for toolbarClass gets UIToolbar.
The arguments must otherwise be subclasses of the respective UIKit classes.
*/
使用这个初始化,可以自定义导航栏视图
通过nil navigationBarClass将让你获得UINavigationBar
通过nil navigationBarClass将让你获得toolbarClass

- (instancetype)initWithNavigationBarClass:(nullable Class)navigationBarClass toolbarClass:(nullable Class)toolbarClass NS_AVAILABLE_IOS(5_0);

// Convenience method pushes the root view controller without animation.
导航控制器跳转到自己的跟视图,没有动画---啥🐦也看不出来

- (instancetype)initWithRootViewController:(UIViewController *)rootViewController; 

// Uses a horizontal slide transition. Has no effect if the view controller is already in the stack.
使用水平滑动过渡。如果视图控制器已经在堆栈中,没有影响的。---啥子意思??
就是简单的push,后面啥意思------????

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; 

// Returns the popped controller.
回到上一级控制器

- (nullable UIViewController *)popViewControllerAnimated:(BOOL)animated; 

// Pops view controllers until the one specified is on top. Returns the popped controllers.

返回到一个指定的视图控制器-----push太多了

- (nullable NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; 

// Pops until there's only a single view controller left on the stack. Returns the popped controllers.
返回到导航控制器的第一个控制器,就是rootConreoller

- (nullable NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated; 

导航控制器的其他属性

//栈顶的控制器
@property(nullable, nonatomic,readonly,strong) UIViewController *topViewController; // The top view controller on the stack.
//模态控制器存在,返回该控制器,否则,返回栈顶的控制器
有资料这样写--
//当前显示的控制器 只读 visibleViewController和哪个导航栈没有关系,只是当前显示的控制器,也就是说任意一个导航的visibleViewController所返回的值应该是一样的
@property(nullable, nonatomic,readonly,strong) UIViewController *visibleViewController; // Return modal view controller if it exists. Otherwise the top view controller.
//当前导航控制器栈里头的控制器数组
@property(nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers; // The current view controller stack.

方法

// If animated is YES, then simulate a push or pop depending on whether the new top view controller was previously in the stack.

/ /如果动画是肯定的,那么模拟推动或者流行取决于新的顶部视图控制器在堆栈之前。
有资料这样写--
//替换栈中的视图控制器数组---同意,妈蛋,翻译下来怎么不一样的这么厉害,我太菜??过四级了呀!!
- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated NS_AVAILABLE_IOS(3_0); 
导航栏是否隐藏
@property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;

设置导航栏消失或者出现,是否以动画的形式

// Hide or show the navigation bar. If animated, it will transition vertically using UINavigationControllerHideShowBarDuration.

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated; 

// The navigation bar managed by the controller. Pushing, popping or setting navigation items on a managed navigation bar is not supported.
控制器管理navigation bar ,push,pop,或者设置navigation items,navigationBar都不支持

@property(nonatomic,readonly) UINavigationBar *navigationBar; 

// Defaults to YES, i.e. hidden.
//toolbar是否隐藏

@property(nonatomic,getter=isToolbarHidden) BOOL toolbarHidden NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; 

// Hide or show the toolbar at the bottom of the screen. If animated, it will transition vertically using UINavigationControllerHideShowBarDuration.
隐藏或显示屏幕的底部的工具栏。如果动画,它将使用UINavigationControllerHideShowBarDuration这个时间垂直过渡。

- (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; 

// For use when presenting an action sheet.
/ /当呈现一个动作表单使用。

@property(null_resettable,nonatomic,readonly) UIToolbar *toolbar NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED; 

//委托

@property(nullable, nonatomic, weak) id<UINavigationControllerDelegate> delegate;

//边缘侧滑返回手势

@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

//展示视图控制器

- (void)showViewController:(UIViewController *)vc sender:(nullable id)sender NS_AVAILABLE_IOS(8_0); // Interpreted as pushViewController:animated:

/ / /键盘出现的时候,导航控制器的navigationBar工具栏会隐藏。在键盘dismiss后,两个bar依然Hidden,但是在内容区域点击,他们就又出来了---IOS8特性

@property (nonatomic, readwrite, assign) BOOL hidesBarsWhenKeyboardAppears NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

/// When the user swipes, the navigation controller's navigationBar & toolbar will be hidden (on a swipe up) or shown (on a swipe down). The toolbar only participates if it has items.
导航栏,在用户向上刷的时候Hidden,在向下刷NotHidden,至于工具栏应该是有内容的时候才参与吧。。。---我猜的------IOS8特性

@property (nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

/// The gesture recognizer that triggers if the bars will hide or show due to a swipe. Do not change the delegate or attempt to replace this gesture by overriding this method.
//获取能够隐藏navigationBar的滑动手势 只读

@property (nonatomic, readonly, strong) UIPanGestureRecognizer *barHideOnSwipeGestureRecognizer NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

/// When the UINavigationController's vertical size class is compact, hide the UINavigationBar and UIToolbar. Unhandled taps in the regions that would normally be occupied by these bars will reveal the bars.
//当设置为true时,横向方向时隐藏NavigationBar

@property (nonatomic, readwrite, assign) BOOL hidesBarsWhenVerticallyCompact NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

/// When the user taps, the navigation controller's navigationBar & toolbar will be hidden or shown, depending on the hidden state of the navigationBar. The toolbar will only be shown if it has items to display.
//当设置为true时,如果有没处理的点击手势就会隐藏和显示navigationBar

@property (nonatomic, readwrite, assign) BOOL hidesBarsOnTap NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;

/// The gesture recognizer used to recognize if the bars will hide or show due to a tap in content. Do not change the delegate or attempt to replace this gesture by overriding this method.
//获取能够隐藏navigationBar的点击手势 只读

@property (nonatomic, readonly, assign) UITapGestureRecognizer *barHideOnTapGestureRecognizer NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;


知识点1:UINavigationController UINavigationBar UINavigationItem三者的关系
通俗地说就是,UINavigationController是个容器,里面可以装很多UIViewController。装这么多UIViewController让用户怎么控制它们呢,总得有个工具吧。这个工具就是UINavigationBar。一个容器就这么一个bar,相当于控制台吧。但是,管理那么多UIViewController,控制台上得按钮啊、标题啊,都千篇一律是不是看起来太无聊了。为了解决这个问题,UINavigationController为每个UIViewController生成一个UINavigationItem,通过这个UINavigationItem可以改变控制台“上面”得按钮和标题。如果你不自定义UINavigationItem,UINavigationController会使用默认的;
UINavigationController是UIViewController的子类,UINavigationBar是UIView的子类。
UINavigationBar是UINavigationController的一个组成部分,就是上面的那个导航栏。
UINavigationBar又有UINavigationItem组成。
UINavigationItem则有title,按钮,提示文本等组成,就是我们看到的title文字,右上角的按钮。
navigation item在navigation Bar代表一个viewController,具体一点儿来说就是每一个加到navigationController的viewController都会有一个对应的navigationItem一个导航控制器控制多个视图,NavigationBar上的leftItem,rightItem,title是由当前的视图控制器控制的


二:UINavigationControllerDelegate的定义内容

/**
 *  将要显示目标控制器
 *
 *  @param navigationController 当前导航控制器
 *  @param viewController       目标视图控制器
 *  @param animated             动画
 */
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
/**
 *  目标控制器最终显示
 *
 *  @param navigationController 当前导航控制器
 *  @param viewController       目标视图控制器
 *  @param animated             动画
 */
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
/**
 *  横竖屏切换
 *
 *  @param navigationController 当前导航控制器
 *
 *  @return 横竖屏方向
 */
- (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
/**
 *  横竖屏切换
 *
 *  @param navigationController 当前导航控制器
 *
 *  @return 横竖屏方向
 */
- (UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation:(UINavigationController *)navigationController NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
/**
 *  转场动画
 *
 *  @param navigationController 当前导航控制器
 *  @param animationController  动画控制器
 *
 *  @return 转场动画
 */
- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                                   interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0);
/**
 *  转场动画
 *
 *  @param navigationController 当前导航控制器
 *  @param operation            动画类型枚举
 *  @param fromVC               起始视图控制器
 *  @param toVC                 目标视图控制器
 *
 *  @return 转场动画
 */
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                            animationControllerForOperation:(UINavigationControllerOperation)operation
                                                         fromViewController:(UIViewController *)fromVC
                                                           toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);

三:UIViewController (UINavigationControllerItem)分类

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

@end

知识点1:UINavigationControllerItem因为扩展在UIViewController上,所以可以直接在UIViewController中使用下面的代码进行调用跟设置;
self.navigationItem.title = @"UINavigationBar使用总结";


四:UIViewController (UINavigationControllerContextualToolbarItems)分类 拓展toolbarItems属性

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

@end

五:关于UINavigationBar定义内容

NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationBar : UIView <NSCoding, UIBarPositioning> 

@property(nonatomic,assign) UIBarStyle barStyle;

@property(nullable,nonatomic,weak) id<UINavigationBarDelegate> delegate;

//Translucent设置成透明度,设置成YES会有一种模糊效果
@property(nonatomic,assign,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(3_0) UI_APPEARANCE_SELECTOR; 

//UINavigationBar上面不只是简单的显示标题,它也将标题进行了堆栈的管理,每一个标题抽象为的对象在iOS系统中是UINavigationItem对象,我们可以通过push与pop操作管理item组。
//向栈中添加一个item,上一个item会被推向导航栏的左侧,变为pop按钮,会有一个动画效果
- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated;
//pop一个item
- (nullable UINavigationItem *)popNavigationItemAnimated:(BOOL)animated; 
//当前push到最上层的item
@property(nullable, nonatomic,readonly,strong) UINavigationItem *topItem;
//仅次于最上层的item,一般式被推向导航栏左侧的item
@property(nullable, nonatomic,readonly,strong) UINavigationItem *backItem;
//获取堆栈中所有item的数组
@property(nullable,nonatomic,copy) NSArray<UINavigationItem *> *items;
//设置一组item
- (void)setItems:(nullable NSArray<UINavigationItem *> *)items animated:(BOOL)animated; 

//系统类型按钮文字颜色
@property(null_resettable, nonatomic,strong) UIColor *tintColor;

//通过barTintColor来设置背景色
@property(nullable, nonatomic,strong) UIColor *barTintColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;  

//设置工具栏背景和阴影图案
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
- (nullable UIImage *)backgroundImageForBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;

//通过背景图片来设置导航栏的外观
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

- (nullable UIImage *)backgroundImageForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

//背景阴影图片 - 即分割线
@property(nullable, nonatomic,strong) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;

//标题的富文本
@property(nullable,nonatomic,copy) NSDictionary<NSString *,id> *titleTextAttributes NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

//标题垂直偏移
- (void)setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

- (CGFloat)titleVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

//设置返回按钮的图片
@property(nullable,nonatomic,strong) UIImage *backIndicatorImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;
@property(nullable,nonatomic,strong) UIImage *backIndicatorTransitionMaskImage NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;

@end

UINavigationBar是用于实现管理层级关系内容的组件,直接继承自UIView。通常用在UINavgationController类中,用于管理和显示UINavgationController的subViewController , 同时UINavgationBar也可以单独使用,添加至任何的UIView中。UINavigationBar比较重要的属性为,左侧按钮,中间的标题,以及右侧按钮。在平时的应用程序中,我们常常使用到自定义UINavigationBar来完成导航条的设置。


知识点1:导航栏全局属性设置

//全局设置导航栏主题
- (void)setNavigationControllerAppearance {
    [UINavigationBar appearance].barStyle  = UIBarStyleBlack;
    [[UINavigationBar appearance] setBarTintColor:[UIColor colorWithWhite:0.1 alpha:0.5]];
    [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
}

全局设置导航栏的好处有两个:一是不用对每个NavigationBar进行设置;二是方便做主题管理,切换主题,只需要更改全局设置即可。

知识点2:自定义返回的图标并去除文字,要同时设置setBackIndicatorImage、setBackIndicatorTransitionMaskImage

[self.navigationController.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"]];  
  
[self.navigationController.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"navibar_back_btn_bg_normal.png"]];   
  
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:nil];  

self.navigationItem.backBarButtonItem = backItem;

知识点3:设置导航条底部线条的颜色

颜色转图片的代码:

@implementation UIImage (ColorImage)

+ (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

@end


设置导航栏底部线条颜色的代码:

    UINavigationBar *navigationBar = self.navigationController.navigationBar;
    [navigationBar setBackgroundImage:[[UIImage alloc] init]
                       forBarPosition:UIBarPositionAny
                           barMetrics:UIBarMetricsDefault];
    //此处使底部线条颜色为红色
    [navigationBar setShadowImage:[UIImage imageWithColor:[UIColor redColor]]];

知识点4:隐藏导航条底部线条

//找查到Nav底部的黑线
- (UIImageView *)findHairlineImageViewUnder:(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 findHairlineImageViewUnder:subview];
        if (imageView) {
            return imageView;
        }
    }
    return nil;
}

然后设置这个UIImageView为隐藏就可以了;


方法二:这种主要是隐藏后没办法再显示出来

UINavigationBar *navigationBar = self.navigationController.navigationBar;
    //设置透明的背景图,便于识别底部线条有没有被隐藏
    [navigationBar setBackgroundImage:[[UIImage alloc] init]
                       forBarPosition:UIBarPositionAny
                           barMetrics:UIBarMetricsDefault];
    //此处使底部线条失效
    [navigationBar setShadowImage:[UIImage new]];

六:关于UINavigationItem的定义

NS_CLASS_AVAILABLE_IOS(2_0) @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;

- (void)setHidesBackButton:(BOOL)hidesBackButton animated:(BOOL)animated;
//左边数组Item
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *leftBarButtonItems NS_AVAILABLE_IOS(5_0);
//右边数组Item
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems NS_AVAILABLE_IOS(5_0);

- (void)setLeftBarButtonItems:(nullable NSArray<UIBarButtonItem *> *)items animated:(BOOL)animated NS_AVAILABLE_IOS(5_0);

- (void)setRightBarButtonItems:(nullable NSArray<UIBarButtonItem *> *)items animated:(BOOL)animated NS_AVAILABLE_IOS(5_0);

//通过指定该属性为YES,可以让leftBarButtonItem和backBarButtonItem同时显示,其中leftBarButtonItem显示在backBarButtonItem的右边 默认值为NO
@property(nonatomic) BOOL leftItemsSupplementBackButton NS_AVAILABLE_IOS(5_0);
//左边Item
@property(nullable, nonatomic,strong) UIBarButtonItem *leftBarButtonItem;
//右边Item
@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;

- (void)setLeftBarButtonItem:(nullable UIBarButtonItem *)item animated:(BOOL)animated;

- (void)setRightBarButtonItem:(nullable UIBarButtonItem *)item animated:(BOOL)animated;

@end

UINavigationController会为每一个入栈的UIViewController生成一个UINavigationItem. UIViewController通过修改UINavigationItem可以控制UINavigationBar上的按钮和标题等

知识点1:关于UINavigationItem内容

你可以通过设置self.navigationItem.leftBarButtonItem为某个ButtonItem,
self.navigationItem.leftBarButtonItem
self.navigationItem.rightBarButtonItem
self.navigationItem.backBarButtonItem
self.navigationItem.titleView等等
注:1、这里的self 指的是UIViewController。
2、如果你在新视图中不修改backBarButtonItem 或leftBarButtonItem UINavigationController 会自动添加左边返回按钮用以返回了一个视图。总体的显示原则如下:
1)、Left side of the navigationBar 左按钮
a)如果当前的viewController设置了leftBarButtonItem,则显示当前VC所自带的leftBarButtonItem。
b)如果当前的viewController没有设置leftBarButtonItem,且当前VC不是rootVC的时候,则显示前一层VC的backBarButtonItem。如果前一层的VC没有显示的指定backBarButtonItem的话,系统将会根据前一层VC的title属性自动生成一个back按钮,并显示出来。
c)如果当前的viewController没有设置leftBarButtonItem,且当前VC已是rootVC的时候,左边将不显示任何东西。
此处注意:5.0中新增加了一个属性leftItemsSupplementBackButton,通过指定该属性为YES,可以让leftBarButtonItem和backBarButtonItem同时显示,其中leftBarButtonItem显示在backBarButtonItem的右边。
2)、title 标题
a)如果当前VC通过 .navigationItem.titleView指定了自定义的titleView,系统将会显示指定的titleView,此处要注意自定义titleView的高度不要超过navigationBar的高度,否则会显示出界。
b)如果当前VC没有指定titleView,系统则会根据当前VC的title或者当前VC的navigationItem.title的内容创建一个UILabel并显示,其中如果指定了navigationItem.title的话,则优先显示navigationItem.title的内容。
3)、Right side of the navigationBar  右按钮
a)如果当前VC指定了rightBarButtonItem的话,则显示指定的内容。
b)如果当前VC没有指定rightBarButtonItem的话,则不显示任何东西。

知识点2:相关属性运用

NavigationBar设置中间的标题或者自定义View
[self.navigationItem setTitle:@"旅行"];
[self.navigationItem setTitleView:xxxx];

单个或多个左右Item设置:单个leftItem设置:
UIBarButtonItem  *leftBarButton = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"BackIcon"] style:UIBarButtonItemStylePlain target:self action:nil];
 [leftBarButton setTintColor:[UIColor colorWithWhite:0 alpha:1]]; 
self.navigationItem.leftBarButtonItem = leftBarButton;

多个rightItem设置:
UIBarButtonItem *firstItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:nil];
UIBarButtonItem *secondItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:nil];
NSArray *rightItems = @[firstItem, secondItem];
self.navigationItem.rightBarButtonItems = rightItems;

知识点3:设置偏移值

// 返回按钮内容左靠
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
// 让返回按钮内容继续向左边偏移10
button.contentEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];

七:UIBarButtonItem定义内容

NS_CLASS_AVAILABLE_IOS(2_0) @interface UIBarButtonItem : UIBarItem <NSCoding>

- (instancetype)init NS_DESIGNATED_INITIALIZER;
//初始化
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithImage:(nullable UIImage *)image style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action;
- (instancetype)initWithImage:(nullable UIImage *)image landscapeImagePhone:(nullable UIImage *)landscapeImagePhone style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action NS_AVAILABLE_IOS(5_0); 
- (instancetype)initWithTitle:(nullable NSString *)title style:(UIBarButtonItemStyle)style target:(nullable id)target action:(nullable SEL)action;
- (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(nullable id)target action:(nullable SEL)action;
//自定义视图
- (instancetype)initWithCustomView:(UIView *)customView;

//样式
@property(nonatomic)         UIBarButtonItemStyle style;            // default is UIBarButtonItemStylePlain
@property(nonatomic)         CGFloat              width;           
@property(nullable, nonatomic,copy)    NSSet<NSString *>   *possibleTitles;   // default is nil
//自定义视图
@property(nullable, nonatomic,strong)  __kindof UIView     *customView;       
@property(nullable, nonatomic)         SEL                  action;           // default is NULL
@property(nullable, nonatomic,weak)    id                   target;           // default is nil

- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (nullable UIImage *)backgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;


- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;
- (nullable UIImage *)backgroundImageForState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;

@property(nullable, nonatomic,strong) UIColor *tintColor NS_AVAILABLE_IOS(5_0);


- (void)setBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; 
- (CGFloat)backgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;


- (void)setTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; 
- (UIOffset)titlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

- (void)setBackButtonBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (nullable UIImage *)backButtonBackgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

- (void)setBackButtonTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (UIOffset)backButtonTitlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;


- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;
- (CGFloat)backButtonBackgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;

@end

知识点1:UIBarButtonSystemItem的样式介绍

typedef NS_ENUM(NSInteger, UIBarButtonSystemItem) {
    UIBarButtonSystemItemDone,//显示完成
    UIBarButtonSystemItemCancel,//显示取消
    UIBarButtonSystemItemEdit,  //显示编辑
    UIBarButtonSystemItemSave, //显示保存 
    UIBarButtonSystemItemAdd,//显示加号
    UIBarButtonSystemItemFlexibleSpace,//什么都不显示,占位一个空间位置
    UIBarButtonSystemItemFixedSpace,//和上一个类似
    UIBarButtonSystemItemCompose,//显示写入按钮
    UIBarButtonSystemItemReply,//显示循环按钮
    UIBarButtonSystemItemAction,//显示活动按钮
    UIBarButtonSystemItemOrganize,//显示组合按钮
    UIBarButtonSystemItemBookmarks,//显示图书按钮
    UIBarButtonSystemItemSearch,//显示查找按钮
    UIBarButtonSystemItemRefresh,//显示刷新按钮
    UIBarButtonSystemItemStop,//显示停止按钮
    UIBarButtonSystemItemCamera,//显示相机按钮
    UIBarButtonSystemItemTrash,//显示移除按钮
    UIBarButtonSystemItemPlay,//显示播放按钮
    UIBarButtonSystemItemPause,//显示暂停按钮
    UIBarButtonSystemItemRewind,//显示退后按钮
    UIBarButtonSystemItemFastForward,//显示前进按钮
    UIBarButtonSystemItemUndo,//显示消除按钮
    UIBarButtonSystemItemRedo ,//显示重做按钮
    UIBarButtonSystemItemPageCurl ,//在tool上有效
};
例如:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(right:)];


- (void)right:(id)sender
{
    NSLog(@"rightBarButtonItem");
}

知识点2:自定义UIView的UIBarButtonItem

UIView *testView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 60)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:testView];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容