iOS--UINavigationController学习笔记
来源:互联网 发布:上海婚纱摄影推荐知乎 编辑:程序博客网 时间:2024/06/01 21:43
1.简介
UINavigationController:是iOS常见的一种容器型Controller。官方文档上给出的注释如下
UINavigationController manages a stack of view controllers and a navigation bar.It performs horizontal view transitions for pushed and popped views while keeping the navigation bar in sync.Most clients will not need to subclass UINavigationController.If a navigation controller is nested in a tabbar controller, it uses the title and toolbar attributes of the bottom view controller on the stack.UINavigationController is rotatable if its top view controller is rotatable.Navigation between controllers with non-uniform rotatability is currently not supported.
意思是说,UINavigationController管理着一个viewController的栈和一个navigation bar(navigation bar后面会说)。管理着出于同一层次的viewController的view,包括压栈和出栈(viewController显示滑进和隐藏滑出界)的转场动画,同时还同步管理着顶部navigation bar的状态。大部分的app都不需要实现一个它的子类(对于一般的功能,都具有支持)。如果一个UINavigationController的实例嵌套在一个UITabbarController的实例中,它将使用栈底的viewController的标题和toolbar的属性。UINavigationController的可旋转是和栈顶的viewController保持一致的。现在还不支持同一层次的viewController旋转类型不一致的压栈出栈。
2.常见属性和方法
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController;
以一个viewController为栈底,实例化一个navigation viewcontroller
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
展示一个viewcontroller,压栈操作(可以有动画效果)。
- (nullableUIViewController *)popViewControllerAnimated:(BOOL)animated;
结束并隐藏一个viewcontroller(dealloc),出栈操作(可以有动画效果),返回出栈的viewcontroller
- (nullableNSArray<__kindofUIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
结束并隐藏 在栈中位于一个特殊的viewcontroller之前所有的viewcontroller,并返回
- (nullableNSArray<__kindofUIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated;
出栈到根viewcontroller
@property(nullable,nonatomic,readonly,strong) UIViewController *topViewController;
栈顶viewcontroller
@property(nullable,nonatomic,readonly,strong) UIViewController *visibleViewController;
如果模态viewcontroller存在,返回模态viewcontroller,否则栈顶viewcontroller
@property(nonatomic,copy) NSArray<__kindofUIViewController *> *viewControllers;
当前栈中的元素
- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);
设置栈中的元素,animated=yes,根据当前的栈顶viewcontroller在不在这个viewcontroller数组中,模拟一次push和pop的动画。这就相当于对当前的栈进行了一次整体的刷新
下面的bar属性主要是用来显示顶部的导航栏以及底部的工具栏
@property(nonatomic,getter=isNavigationBarHidden)BOOLnavigationBarHidden;
- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
@property(nonatomic,readonly) UINavigationBar *navigationBar;
@property(nonatomic,getter=isToolbarHidden)BOOLtoolbarHidden NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
- (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
@property(null_resettable,nonatomic,readonly) UIToolbar *toolbar NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;//
delegate,可以在压栈出栈操作中,设置一些动画,以及一些额外的操作
@property(nullable,nonatomic,weak)id<UINavigationControllerDelegate> delegate;
这里需要说一下visibleViewController和topViewController:topViewController永远代表着栈顶元素;visibleViewController代表着当前显示的那个vc,这个vc可能是top vc,也有可能是top vc 展示出来的vc。
3.UINavigationBar
3.1. 导航栏属性设置:
通常我们都会在APPDelegate为整个APP的导航栏做全局性的设置,使用[UINavigationBarappearance]这个方法获得当前的导航栏实例;以及在viewController中对当前页面的导航栏做特殊的设置,使用self.navigationController.navigationBar获得当前的导航栏实例。记住,在viewController中对导航栏的设置,要在这个viewController小时之前还原,否则会覆盖全局的设置,从而影响其他页面的显示。
barTintColor:设置导航栏的整体背景颜色,包括状态栏的背景颜色。如下:
[[UINavigationBarappearance]setBarTintColor:[UIColoryellowColor]];运行的效果如下
tintColor:设置导航栏的按钮的图标和文字颜色(系统提供的),自定义的不在此范围;
[[UINavigationBarappearance]setTintColor:[UIColorredColor]];运行的效果如下
barStyle:设置导航栏的整体风格,有UIBarStyleDefault和UIBarStyleBlack两种选择。对应以下两种运行结果,可以看到UIBarStyleBlack会影响状态栏的颜色以及导航栏的标题颜色。(但是已经对标题的字体颜色都已经赋值的,就不受影响了)
titleTextAttributes:设置导航栏的标题的显示样式,包括UITextAttributeFont - 字体 UITextAttributeTextColor - 文字颜色 UITextAttributeTextShadowColor - 文字阴影颜色 UITextAttributeTextShadowOffset - 偏移用于文本阴影
[[UINavigationBarappearance]setTitleTextAttributes:[NSDictionarydictionaryWithObjectsAndKeys:
[UIColorredColor],NSForegroundColorAttributeName,
[UIFontsystemFontOfSize:18.f],NSFontAttributeName,
nil]];
backgroundImage/shadowImage:设置导航栏的背景和阴影图片
[[UINavigationBarappearance]setBackgroundImage:[UIImageimageNamed:xxx]
forBarMetrics:UIBarMetricsDefault];
[[UINavigationBarappearance]setShadowImage:[UIImageimageNamed:xxx]];
translucent:BOOL,半透明效果。
补充点:前面说到也可以在viewController中对UINavigationBar进行属性设置,基本上都会生效。但是,有些情况下会发现,viewController的(UIStatusBarStyle)preferredStatusBarStyle是不起作用的,原因是因为当前的viewController是嵌套在一个UINavigationController的实例中,最多只会调用UINavigationController的preferredStatusBarStyle,除非将导航栏隐藏,才会调用viewController的preferredStatusBarStyle方法。解决办法:在iOS9之前,App的info.plist文件中,添加View controller-based status bar appearance的值为NO,(意识是说让Application的设置优先于viewController的设置),通过[[UIApplication sharedApplication] setStatusBarStyle:]这个方法来进行设置修改statusBar;但是在iOS9之后,该方法会提示过时⚠️,解决办法是将 View controller-based status bar appearance的值设置YES,然后通过navigationBar.barStyle来设置。然而,现在很多应用都是在iOS7做适配的时候,将View controller-based status bar appearance设为NO,(iOS之前,默认值为NO,iOS之后为YES),iOS7和8对此也都处于兼容状态。9之后会出现警告。
3.2. UINavigationItem以及其与UINavigationBar的关系:
在前面的简介之中,提到UINavigationController管理着一个UIViewController的栈和一个UINavigationBar。其实,一个UINavigationController的实例对应一个UINavigationBar的实例,而一个UINavigationBar的实例同样管理着一个栈,这个栈中的元素就是UINavigationItem。所以,既然一个navigationController对应一个navigationBar,可以推断到UINavigationController的栈和UINavigationBar的栈也是对应的,而两个栈里元素也是一一对应,也就是一个UIViewController的实例也对应着一个UINavigationItem的实例(如果不对应,系统会报异常情况)。在navigationController进行push和pop的同时,navigationBar也在同时做相应的push和pop 。在官方的API中,在UINavigationController.h文件中会有一个UIViewController的一个category,里面定义着一个UINavigationItem的变量。
3.3. 定制导航栏内容
定制导航栏一般都是在viewController中进行自我定制navigationItem。
定制title,使用viewController.title和viewController.navigationItem.title都可以实现导航栏title的定制。补充:设置viewController.title会覆盖viewController.navigationItem.title,设置viewController.navigationItem.title不会覆盖viewController.title。
有的时候需要将导航栏标题修改为一个我们自己想要的UIView,只要将我们需要的UIView赋值给viewController.navigationItem.titleView。比如一个button,一张图片,一个搜索框等等
定制left/rightBarButtonItem:在导航栏中,左右两边通常都会有一些button或者需要交互的view。这时候就需要给viewController.navigationItem设置left/rightBarButtonItem,可定制成任意样式。
在导航栏中,如果本身没有对viewController.navigationItem.leftBarButtonItem进行定制,会优先展示上一个页面的backBarButtonItem;如果上一个页面也没有设置backBarButtonItem,就会展示一个系统的回退按钮和上一个页面的title。
iOS--UINavigationController学习笔记二
0 0
- iOS--UINavigationController学习笔记
- iOS--UINavigationController学习笔记二
- iOS--UINavigationController学习笔记三
- iOS-UINavigationController的学习
- ios-UINavigationController 详解
- IOS学习笔记13—UINavigationController
- IOS学习笔记(5)UINavigationController UITabBarController
- iOS学习笔记-7 UINavigationController定制
- IOS学习笔记(5)UINavigationController UITabBarController
- iOS Programming 学习笔记 - 05 UINavigationController
- iOS学习笔记(6)UINavigationController
- ios客户端学习-AppDelegate获取UINavigationController及UIStoryboard
- ios学习:UINavigationController导航
- ios学习:UINavigationController导航
- IOS学习之UINavigationController
- UINavigationController学习笔记
- [iOS]UINavigationController UITabBarController UITableView学习笔记
- [iOS]UINavigationController UITabBarController UITableView学习笔记
- MATLAB函数运算
- IIR型高斯滤波的原理及实现
- HDU 5673 Robot
- 分类与扩展
- 求最长有效匹配括号子串的长度(Longest Valid Parentheses)
- iOS--UINavigationController学习笔记
- link和@import的区别
- 几个Android开发中遇到的问题
- servlet详解(第三篇)
- android 的四种枚举Context.MODE_PRIVATE
- 安装Baidu Eclipse插件
- 【codevs】基础合集(二)
- oracle数据库学习1
- redis持久化探究