self.navigationController.navigationItem 与 self.navigationItem 关系对比与分析

本文深入解析iOS中UINavigationController、UINavigationBar及UINavigationItem的关系,介绍如何配置导航栏的样式和功能,包括自定义导航栏的高度和交互手势。

http://blog.youkuaiyun.com/luoyeffcs/article/details/16106707

以下两者对比

    self.navigationController.navigationItem = customItem;

    self.navigationItem = customItem;

我们都知道navigationItem是UIViewController的一个属性,这个属性是为 UINavigationController服务的。文档中是这么解释的“The navigation item used to represent the view controller in a parent’s navigation bar. (read-only)”,即navigation item在navigation Bar代表一个viewController,具体一点儿来说就是每一个加到navigationController的viewController都会有一个对应的navigationItem,该对象由viewController以懒加载的方式创建,稍后我们可以在对象中堆 navigationItem进行配置,可以设置leftBarButtonItem, rightBarButtonItem, backBarButtonItem, title以及prompt等属性。前三个每一个都是一个UIBarButtonItem对象,最后两个属性是一个NSString类型描述,注意添加该描述以后NavigationBar的高度会增加30,总的高度会变成74(不管当前方向是Portrait还是Landscape,此模式下 navgationbar都使用高度44加上prompt30的方式进行显示)。当然如果觉得只是设置文字的title不够爽,你还可以通过 titleview属性指定一个定制的titleview,这样你就可以随心所欲了,当然注意指定的titleview的frame大小,不要显示出界。

1.关系分析

2.关系综述

3.概念点

4.疑问


1.关系分析

UIBarItem-> UIBarButtonItem -> UINavigationItem

1.1 UIBarItem:

UIBarItem类是一个可以放置在Bar之上的所有小控件类的抽象类。继承了该基类所有子类在外观上类似于一个Button,它们都有一个标题,图片,动作以及目标,这点可以从其子类的初始化方法处看到。


1.2 UIBarButtonItem:

专门用来放在UIToolbar 或者 UINavigationBar的特殊button.基本行为跟button是一样的。另外从IOS5开始的Customizing Appearance 增加了一系列的方法调整显示。


1.3 UINavigationItem: NSObject  

(包含了当前页面导航栏上需要显示的全部信息)

title,prompt,titleView,leftBarButtonItem,rightBarButtonItem,backBarButonItem


1.4 UINavigationBar :UIView

NavigaitonBar就是导航栏,位于屏幕的上方,管理整个NavigationControllernavigationItem,即类似navigationcontroller一样提供了一个栈来管理item


1.5 UINavigtionController :UIViewController

包含:viewcontrollersnavigationbartoolbar


1.6 navigationbarUIView

包含:items(UINavigationItem)


1.7 viewController

包含navigationitemtoolItem.  这两个属性控制了当前页面当前页面的navigationbartoolbar的外观。


2.关系综述

navigationcontroller直接控制viewcontrollers,然后包含的navigationbar形成整个nv的导航栏,bar并包含整个navigationItem的栈,管理整个nvnavigationitem NSArray *items 属性)。

navigationItem包含了bar视图的全部元素(如title,tileview,backBarButtonItem等),受当前viewcontroller管理,即bar形成整个nv的导航视图,然后每个nv页面的导航栏元素由所在页面的navigationItem管理。即设置当前页面的左右barbutton,用 self.navigationItem.leftBarButtonItem等。


3.概念点

3.1 

UINavigationController 是一个viewController

UINavigationBar 是一个view

UINavigationItem 是一个NSObject

UIBarButtonItem 是一个 UIBarItem,是一种专门放在bar上的特殊button

UIBarItem是一个NSObject,是是各种itme的父类


3.2 title

self.navigationItem.title,self.tabBarItem.title,self.title关系:

由于view controller本身包含navigationItemtabBarItem,所以可以单独对其title赋值,self.title会重写另外两个的值,只是提供的一种便利方法。


3.3 self.navigationItem,self.navigationController.navigationItem

self.navigationItem  是定制当前view 导航栏。根据当前的资料看,self.navigationController.navigationItem 是应该被忽视的属性,navigationcontroller继承与view controller,所以会有这个属性,但没有任何作用。

不过有人说,“They are Different. If you dynamically add UINavigationController, then you use self.navigationController.navigationItem.”但是没有得到验证,这点我也不认可。


3.4 navigationbar 高度 可更改

UINavigationBar *bar = [self.navigationController navigationBar];

    CGFloat navBarHeight = 70.0f;

    CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, navBarHeight);

    [bar setFrame:frame];


3.5 navigationbar prompt

prompt 是一个NSString类型描述,注意添加该描述以后NavigationBar的高度会增加30,总的高度会变成74(不管当前方向是Portrait还是Landscape,此模式下navgationbar都使用高度44加上prompt30的方式进行显示)

如:

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

self.title=@"HAH";



3.6 navigation barinteractivePopGestureRecognizer

navigation bar 可以修改barstyle transulucent,不能直接修改 frame,bounds,alpha等属性。可以通过initWithNavigationBarClass方法指定自己的navigationbar

IOS7 多了interactivePopGestureRecognizer,看资料说 ios7 UINavigationController 自动就加入了手势返回 前提是不能自定义leftBarButtonItem,自定义了leftBarButtonItem手势就失效了,待研究。


4.疑问

4.1控件都继承于uiview,都有tintcolorbackgroundcolor属性,那两者主要有什么区别呢?

4.2UIBarPosition UIBarMetrics 区别?


private func handleViewWillAppear() { updateTabNamesAfterRelogin() navigationController?.navigationBar.barStyle = .default if isFirst { isFirst = false if appContext.isVmsLogin && !showLocalDeviceOnly && isDeviceListOld { reqSingleSiteInfoCode = appContext.requestSingVmsSiteInfo(bySiteId: self.currentSiteInfo?.siteId ?? 0) } } if needVmsRefresh && appContext.isVmsLogin && !showLocalDeviceOnly { needVmsRefresh = false if isDeviceListOld { reqSingleSiteInfoCode = appContext.requestSingVmsSiteInfo(bySiteId: self.currentSiteInfo?.siteId ?? 0) } if let vc = self.pageController.viewControllers?.first as? OnlineDeviceListViewController { vc.forceRefresh() } } // TODO: 替换文案 localDeviceCountLabel.text = String(format: LocalizedString(key: deviceListNumberOfDevices), localDeviceCount) LocalDeviceViewHeight.constant = CGFloat(0) localDeviceView.isHidden = true if !appContext.isLogin { //未登录 if showLocalDeviceOnly { if localDeviceCount == 0 { self.navigationItem.rightBarButtonItems = [addButtonmItem] } else { self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem] } moreSiteButton.isHidden = localDeviceCount == 0 tabBarCollectionView.isHidden = localDeviceCount == 0 } else { //如果未登录则左边按钮不显示 self.navigationItem.leftBarButtonItems = [mineButtonItem] //右边显示所有按钮 self.navigationItem.rightBarButtonItems = [addButtonmItem,negativeButtonItem] tabBarCollectionView.isHidden = true } scrollView.setContentOffset(CGPoint(x: 0, y: 62), animated: false) } else { //如果登录了则左边按钮显示 if showLocalDeviceOnly { moreSiteButton.isHidden = localDeviceCount == 0 tabBarCollectionView.isHidden = localDeviceCount == 0 if localDeviceCount == 0 { self.navigationItem.rightBarButtonItems = [addButtonmItem] } else { self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem, searchItem] } removeLeftBarButtonItem() addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) } else { moreSiteButton.isHidden = false tabBarCollectionView.isHidden = false if appContext.isVmsLogin { // 登录状态VMS if isDeviceListOld { removeLeftBarButtonItem() addCustomNavigationLeftBarButtonItem(title: nil, image: TPImageLiteral("common_light_back_nor")) self.navigationItem.rightBarButtonItems = [searchItem, changeDisplayTypeItem] } else { // tab新版VMS不能滚动 tabBarCollectionView.isScrollEnabled = true // addLeftBarButtonItem() if appContext.loginType == .cloud { self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem] } else { self.navigationItem.rightBarButtonItems = [] } } } else { // 登录状态个人版 reqVmsOrgListCode = appContext.requestVMSOrganizationList(withUsername: appContext.accountUsername, password: appContext.accountPassword ?? "") // removeLeftBarButtonItem() // if let hasVms = UserDefaults.standard.object(forKey: kHasCloudVMSOrganization) as? Bool, hasVms { // addLeftBarButtonItem() // } self.navigationItem.rightBarButtonItems = [addButtonmItem, negativeButtonItem] } } scrollView.setContentOffset(CGPoint(x: 0, y: 62), animated: false) } if !appContext.isLogin && !showLocalDeviceOnly{ showEmpty() return } else if firstAppear { firstAppear = false restore() } else if shouldRecreate { shouldRecreate = false reload() } //评分引导 self.isNeedEvaluation() // 当tab栏个数等于1的时候禁止左右滑动 for view in pageController.view.subviews { if let subView = view as? UIScrollView { subView.isScrollEnabled = tabNames.count > 1 // 优先处理屏幕边缘滑动手势 if let gestureRecognizers = self.view.gestureRecognizers { for recognizer in gestureRecognizers { if recognizer is UIScreenEdgePanGestureRecognizer { subView.panGestureRecognizer.require(toFail: recognizer) } } } } } registerCallback() if !appContext.isLocalVMSLogin { addTitleView() } else if !isDeviceListOld && !showLocalDeviceOnly { let titleLabel = UILabel() titleLabel.textAlignment = .natural titleLabel.font = .boldProjectFont(ofSize: 22) titleLabel.textColor = .tpbTextPrimary titleLabel.text = appContext.isVmsLogin ? appContext.accountInfo.currentVmsName : LocalizedString(key: accountMyVIGI) let titleItem = UIBarButtonItem.init(customView: titleLabel) navigationItem.leftBarButtonItems = [titleItem] } guard let vc = self.pageController.viewControllers?.first as? OnlineDeviceListViewController else { commonLoad() return } vc.deviceOnlineStatus = currentDeviceOnlineType }
11-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值