之前一直有些疑惑,到底控制器的不同的展示形式有什么区别,今天就查了一些资料,做了一个小结。
在一个app中,会存在多个控制器,多个控制器的存在就会存在控制器的跳转问题。
跳转的形式包涵:
1.连线跳转(根据绑定的id进行控制器的跳转)
2.modal方式
3.navigationController/tabBarController方式
连线跳转的分类:
1.自动型:点击控件后,自动跳转到一下个控制器(action-push方式)
2.手动型:需要借助代码来手动完成
手动型,是指从来源控制器拖到目标控制器.(manual – push 方式),手动型需要设置 storyboard segue 中的identify 标记.手动型要调用一下方法:
[self performSegueWithIdentifier:ID sender:nil];
系统会调用:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
注:向下一个控制器顺序传递数据可以在此方法中书写.
Modal方式,该方式是系统默认的方式,它是从系统底部往上走,覆盖原来的控制器。
使用步骤:
1.创建要跳转到的控制器
2.跳转和关闭
[self presentViewController:创建的控制器];
[self dismissViewController:YES];
3.子控制器是在dismiss之后才会销毁掉
push和pop方式,该方法用于navigationController的跳转.
使用步骤:
1.创建要跳转的控制器(一定要先设置根控制器)
2.跳转和退出
[self.navigationController pushViewController:vc animated:YES];
3.使用UINavigationController的时候,UINavigationController会给所有的目标控制器套上导航条,完成push之后会自动在导航条上生成一个item返回按钮,该按钮可以直接返回上一层的控制器。
(注: 使用UINavigationController设置导航栏的时候只需要设置一次,之后派生的导航栏都和根控制器的导航栏一样.该导航栏的设置是在 initialize 方法中的设置外观代理对象来完成的)
注: UITabBarController要把所有要跳转的控制器一次性加载完成,它的子控制器的同时存在的,并不会因为跳转到其他子控制器而销毁.加载子控制器的时候有两种方式: addChildViewController:VC(加载一个子控制器). viewControllers(加载多个子控制器)其返回值是一个数组,可以将控制器直接加载到数组中并且要注意加载到数组中的顺序就是加载到 tabBar 中的显示的顺序.
不同跳转方式的区别:
1.push-pop需要在navigationController中使用,方式是以栈的方式进行控制器的跳转,进栈的时候将新进来的控制器放在栈顶,是以侧滑的方式进入控制器
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
退出的时候可以有三种方式:
控制器进入的时候是以栈的形式进入的,即新进入的控制器是从右侧进入,将之前的控制器推到左侧,退出的时候将栈顶控制器直接移除。(注tabBarController中并不移除控制器,只是来回的切换)
移除栈顶控制器:
- (UIViewController *)popViewController;
回到制定的子控制器:
- (NSArray *)popViewController;
回到根控制器
- (NSArray *)popToRootViewController;
2 modal 方式:
任何控制器都可以通过 modal 方式来进行跳转,是一个通用性的跳转方式,其默认效果是从下往上走,直到完全覆盖上面的控制器.被覆盖的控制器并没有销毁.
3 以 push 方式加载的控制器会在子控制器上加上一个返回按钮,但 modal 方式不会自动添加,返回按钮要自己创建.
4 modal 出来的控制器将原来的控制器完全覆盖,原来的控制器不可点击. 而由于Push 控制器只是在navigationController 中 push 控制器.
4> 补充
4.1为了便于管理控制器,iOS提供了2个比较特殊的控制器
UINavigationControlle UITabBarController.
4.1.2使用的时候一般用UITabBarController控制器作为窗口的根控制器,然后将UINavigationControlle 做为UITabBarController的根控制器,再加载所需控制器.
4.1.3设置窗口的根控制器步骤
一般通常在Appdelegate里面设置里
> 初始化一个窗口
> 设置窗口的根控制器为导航控制器
> 初始化导航控制器的时候一般要跟一个的控制器.
4.1.4 UINavigationControlle 的特点
> 栈中添加控制器,使用push操作,删除控制器使用pop操作.
> 最先添加的控制器在栈底,而后添加的控制器则在上面,直接使用pop操作,是让栈顶的控制器销毁了,可以指定pop的控制器.但是要注意控制器的循环引用.
> push/pop 的方式是UINavigationControlle 独有的方式,只有UINavigationControlle 和其子类才能够使用该方式.
> pop 控制器的时候可以有popViewController(返回到上一个控制器), popToViewController(返回到指定的控制器), popToRootViewController(返回到根控制器)三种.注:要获取指定的控制器用遍历的方式(XXX isKindOfXXX)
4.2 UITabBarController
4.2.1内部实现原理:以平行的方式管理视图,各个视图之间往往关系并不大,每个加入到UITabBarController的视图都会进行初始化即使当前不显示在界面上,相对比较占用内存。通过给标签控制器的子控制器集合内添加控制器,通过选中的(点击操作)的索引进行控制器的切换.标签控制器内部也是拥有一个子控制器的集合的.
4.2.2 实现原理: UITabBarController是Apple专门为了利用页签切换视图而设计的,在这个视图控制器中有一个UITabBar控件,用户通过点击tabBar进行视图切换。我们知道在UIViewController内部有一个视图,一旦创建了UIViewController之后默认就会显示这个视图,但是UITabBarController本身并不会显示任何视图,如果要显示视图则必须设置其viewControllers属性(它默认显示viewControllers[0])。这个属性是一个数组,它维护了所有UITabBarController的子视图。为了尽可能减少视图之间的耦合,所有的UITabBarController的子视图的相关标题、图标等信息均由子视图自己控制,UITabBarController仅仅作为一个容器存在
4.3 ios8新增的切换方法 showViewController
这个方法应该说是全能型界面切换的方法,它能根据当前的试图控制器情况来决定是用push方法还是普通的Modal方式切换界面。在当前界面是Navi的子VC时,如果用showViewController方法,它会用push方式切换(用pop方式可以返回);而如果当前界面为Modal的界面,就会用modal方式。可以这么说,如果没有特别的要求需要modal界面,你只需要在界面切换时一股脑儿的用showViewController方法就行了,ios的sdk后台基本已经处理好了你该怎么跳转。另外补充一条,在以前,导航控制器的子VC是不能push一个新的导航控制器的,否则运行就会挂掉,但是showVIewController可以做到!