一、简介
在iOS开发中视图的切换是很频繁的,独立的视图应用在实际开发过程中并不常见,除非你的应用足够简单。在iOS开发中常用的视图切换有三种,这三种视图切换的原理各不相同:
- UITabBarController :以平行的方式管理视图,各个视图之间往往关系并不大,每个加入到UITabBarController的视图都会进行初始化即使当前不显示在界面上,相对比较占用内存。
- UINavigationController:以栈的方式管理视图,各个视图的切换就是压栈和出栈操作,出栈后的视图会立即销毁。
- 模态窗口:以模态窗口的形式管理视图,当前视图关闭前其他视图上的内容无法操作。
二、UITabBarController
-
介绍
UITabBarController是Apple专门为了利用页签切换视图而设计的,在这个视图控制器中有一个UITabBar控件,用户通过点击tabBar进行视图切换。我们知道在UIViewController内部有一个视图,一旦创建了UIViewController之后默认就会显示这个视图,但是UITabBarController本身并不会显示任何视图,如果要显示视图则必须设置其viewControllers属性(它默认显示viewControllers[0])。这个属性是一个数组,它维护了所有UITabBarController的子视图。为了尽可能减少视图之间的耦合,所有的UITabBarController的子视图的相关标题、图标等信息均由子视图自己控制,UITabBarController仅仅作为一个容器存在。下面显示了UITabBarController的效果:
-
使用方法
主要流程
- 在AppDelegate中创建TabBarController和需要加载的ViewController。比如分别为tabBar, firstPage, secondPage
- 把视图装进tabBar的viewControllers属性:
tabBar.viewControllers = @[firstPage, secondPage];
- 加载tabBar
修饰
- UITabBarController会一次性初始化所有子控制器,但是默认只加载第一个控制器视图,其他视图控制器只初始化默认不会加载,为了能够将其他子控制器也正常显示在Tab bar中我们访问了每个子视图控制器的视图以便调用其视图加载方法(viewDidLoad)具体操作:
for (UIViewController *controller in tabBar.viewControllers) {
UIView *view = controller.view;
} - 每个视图控制器都有一个tabBarItem属性,通过它控制视图在UITabBarController的tabBar中的显示信息,tabBarItem的属性主要有
- title
- image
- selectedImage
- badgeValue
- tabBarItem的image属性必须是png格式(建议大小32*32)并且打开alpha通道否则无法正常显示。
- 每个视图控制器都有一个tabBarController属性,通过它可以访问所在的UITabBarController
三、UINavigationController
-
介绍
UINavigationController是一个导航控制器,它用来组织有层次关系的视图,在UINavigationController中子控制器以栈的形式存储,只有在栈顶的控制器能够显示在界面中,一旦一个子控制器出栈则会被销毁。UINavigationController默认也不会显示任何视图(这个控制器自身的UIView不会显示),它必须有一个根控制器rootViewController,而且这个根控制器不会像其他子控制器一样被销毁。
下面显示了UITabBarController的效果:
-
使用方法
主要流程
- 创建视图控制器root, firstPage, secondPage
- 在AppDelegate中创建NavigationController并设置其根控制器
RootViewController *root = [[RootViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:tabBar]; - window的rootViewController设置为nav
- 导航跳转动作为堆栈操作,在子视图中可以通过navigationController访问导航控制器, 然后使用pushViewController 方法把FirstPage推进栈内,animated表示切换视图时的动画效果:滑入还是简单切换
[self.navigationController pushViewController:FirstPage animated:Yes];
修饰
在AppDelegate中设置导航栏的全局外观
[[UINavigationBar appearance] setBarTintColor:[UIColor orangeColor]];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];-
在各个层级视图中设置导航栏的选项内容主要有:
self.navigationItem.title
self.navigationItem.leftBarButtonItem
self.navigationItem.rightBarButtonItem
UINavigationController导航是通过上方导航栏进行的(类似的UITabBarController是通过下方UITabBar进行导航),每个放到UINavigationController栈中的子视图都会显示一个导航栏,可以通过子控制器(包括根控制器)的navigationItem访问这个导航栏,修改其左右两边的按钮内容。
默认情况下除了根控制器之外的其他子控制器左侧都会在导航栏左侧显示返回按钮,点击可以返回上一级视图,同时按钮标题默认为上一级视图的标题,可以通过backBarButtonItem修改。下一级子视图左侧返回按钮上的标题的显示优先级为: 导航栏返回按钮backBarButtonItem的标题(注意不能直接给backBarButtonItem的标题赋值,只能重新给backBarButtonItem赋值)、导航栏navigationItem的标题,视图控制器标题。
Tips 使用系统自带的UIBarButtonItem
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 NS_ENUM_AVAILABLE_IOS(3_0),
UIBarButtonSystemItemRedo NS_ENUM_AVAILABLE_IOS(3_0),
UIBarButtonSystemItemPageCurl NS_ENUM_AVAILABLE_IOS(4_0),
};
四、模态窗口
模态窗口使用起来比较容易,一般的视图控制器只要调用两个方法
-
[self presentViewController:secondPage animated:YES completion:nil];
切换到secondPage视图 -
[self dismissViewControllerAnimated:YES completion:nil];
注销当前视图返回上一级视图
这两种方法通过页面按钮来触发。
1
1