美文网首页
UINavigationBar、UINavigationItem

UINavigationBar、UINavigationItem

作者: Faner_NG | 来源:发表于2021-09-05 17:02 被阅读0次

    一、UINavigationBar

    1、导航条navigationbar属于导航控制器,一个导航控制器只有一个导航条。
    2、在一个导航控制器push新页面和pop页面时,导航条是同一个。
    3、在一个视图控制器内改变了导航条的样式,其它控制器的导航条的样式也会改变,也说明了导航条属于导航控制器,而不是每个视图控制器都有一个导航条。
    4、导航条的层级结构
    navigationbar层级:


    image.png

    UIBarBackground视图是比UINavigationBar视图要大

    主要属性:
    1.只读属性Items,backItem,topItem分别表示为数组,上一个控制器,当前控制器(栈顶控制器)

    也就是说UINavigationBar维护着每个VC的navigationItem

    2.translucent
    影响VC.view原点坐标

    • 一个controller的view的原点位置受self.navigationController. navigationBar 的 setTranslucent (BOOL) 属性控制,在 iOS7 以后 translucent 属性默认为 YES。
      translucent 为YES:原点位置坐标为屏幕左顶端,即屏幕坐标系(0 , 0),含义为毛玻璃、半透明效果。
      translucent 为NO:原点位置坐标为导航栏的下边的左顶端,即屏幕坐标系(0 , 64),此时导航栏不透明。
      注意,当我们设置navigationBar的背景图片setBackgroundImage(注意是背景图片不是背景颜色)的时候,坐标起点也会变成(0,64),因为当我们设置背景图片的时候,系统会自动修改translucent为NO。

    • 其实navController不仅有UINavigationBar属性还有个toolbar属性(默认hiddenYES),toolbar的translucent会影响到VC.view的高度,也就是是否延伸到屏幕底部。

    3.tintColor
    bar上的文字按钮颜色

    4.barTintColor
    bar的背景色 ios15之后设置无效
    由于ios15新特性(bar的背景默认是透明,滚动后与关联的scrollview相交才显示bar的背景),需要通过UINavigationBarAppearance设置bar的背景,scrollEdgeAppearance控制与视图不相交时bar的样式,默认是透明的;standardAppearance控制与视图相交时bar的样式,

        if (@available(iOS 15, *)) {
            UINavigationBarAppearance *navBarAppearance = [[UINavigationBarAppearance alloc]init];
            navBarAppearance.backgroundImage = whiteBG;
            navBarAppearance.shadowImage = whiteBG;
            navBarAppearance.titleTextAttributes = @{NSFontAttributeName:[UIFont systemFontOfSize:18]};
    //设置相交状态
            [UINavigationBar appearance].standardAppearance = navBarAppearance;
    //设置不相交状态
            [UINavigationBar appearance].scrollEdgeAppearance = navBarAppearance;
        }
    

    二、UINavigationItem

    UINavigationBar是由UINavigationController管理的,但是它的样式由子控制器的self. navigationItem来设置。

    也就是说UINavigationBar是全局设置的一经修改,这个nav内的所有导航条都发生变化,而UINavigationItem是针对每个VC的,是VC的只读属性
    所以我们应当通过修改UINavigationItem的属性来自定义每个页面的导航条标题/按钮等控件

    主要属性:

    titleView
    leftBarButtonItem,leftBarButtonItems
    rightBarButtonItem,rightBarButtonItems
    backBarButtonItem
    
    栗子:    
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"这是返回" style:UIBarButtonItemStylePlain target:self action:@selector(back)];
    

    三、UIBarButtonItem

    UINavigationItem的left/right/back的样式是通过UIBarButtonItem创建,常用初始化方法:

    UIBarButtonItem : UIBarItem:NSObject
    
    - (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 API_AVAILABLE(ios(5.0)); // landscapeImagePhone will be used for the bar button image when the bar has Compact or Condensed bar metrics.
    - (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;
    

    leftBarButtonItem显示原则:
    1.如果当前的视图控制器设置了leftBarButtonItem,则显示当前VC所自带的leftBarButtonItem。
    2.如果没有设置leftBarButtonItem,且不是根视图控制器的时候,则显示前一层的backBarButtonItem。如果前一层没有指定backBarButtonItem的话,系统将会根据前一层的title属性自动生成一个back按钮,并显示出来。
    3.如果没有设置leftBarButtonItem,且已是根视图控制器的时候,左边不显示任何东西。

    理解:backBarButtonItem不是显示在当前VC的,而是其他VC返回此VC时候的返回按钮,如果其他VC设置了left,那么left优先级高于此VC的backBarButtonItem,例如:
    设置VC1的backBarButtonItem,从VC1push到VC2,如果VC2没设置leftBarButtonItem,那么VC2的左上角返回按钮就是VC1的backBarButtonItem,否则优先左上角显示VC2的leftBarButtonItem

    总结

    navigationcontroller直接控制viewcontrollers集合,然后它包含的navigationbar是整个工程的导航栏,bar有一个用来管理navigationItem的栈。@property(nonatomic, copy) NSArray <UINavigationItem *> *items

    理清以上三者的关系后,可以单独用导航栏UINavigationBar,(不是采用UINavigationController)
    代码方式:
    
    - (void)viewDidLoad{
        UINavigationBar *navBar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)];
        //添加NavigationBar到视图上
        [self.view addSubview:navBar];
        UINavigationItem *navItem = [[UINavigationItem alloc]initWithTitle:@"welcome page"];
        
        UIBarButtonItem *btnlogin = [[UIBarButtonItem alloc]initWithTitle:@"login" style:UIBarButtonItemStyleDone target:self action:@selector(login)];
        navItem.leftBarButtonItem = btnlogin;
        //把NavigationItem添加到导航栏上(进栈)
        [navBar pushNavigationItem:navItem animated:NO];
    }
    

    navigationcontroller和navigationbar是一对一的关系,而navigationbar和navigationItem则是一对多的关系。

    相关文章

      网友评论

          本文标题:UINavigationBar、UINavigationItem

          本文链接:https://www.haomeiwen.com/subject/uzijwltx.html