在做ios 开发的时候,有时候我们需要临时让用户输入信息,常用到的是 presentViewController 这个函数,首先大致了解一下这个函数
这个函数全名如此
<span style="font-family:SimHei;font-size:14px;">- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0); </span>可一看到 第一个参数UIViewcontroller,意味着只要是视图控制器都可以被 present,剩下两个是动画以及完成回调。
官方文档上说调用 present函数 会中断当前工作流程,属于一种临时中断。这也就是跟你push一个viewcontroller的本质区别。
另外需要注意的就是 呈现与被呈现视图之间有一个指向关系。
这是uiviewcongtroller.h 里面的一段代码
<span style="font-family:SimHei;font-size:14px;">// This property has been replaced by presentedViewController. @property(nonatomic,readonly) UIViewController *modalViewController NS_DEPRECATED_IOS(2_0, 6_0); // The view controller that was presented by this view controller or its nearest ancestor. @property(nonatomic,readonly) UIViewController *presentedViewController NS_AVAILABLE_IOS(5_0); // The view controller that presented this view controller (or its farthest ancestor.) @property(nonatomic,readonly) UIViewController *presentingViewController NS_AVAILABLE_IOS(5_0); </span>
好,函数介绍到此。
那实际使用的时候,一般不会出什么问题,不过有些问题值得思考。
比如我最近碰到一个发生在调用时。
<span style="font-family:SimHei;font-size:14px;"> [self presentViewController:photoPicker animated:YES completion:nil];</span>
<span style="font-family:SimHei;font-size:14px;"> [self.view.window.rootViewController presentViewController:controller animated:YES completion:nil]; </span>将调用者由self 替换为 当前app的rootviewcontroller,这段文字就没有了。于是引发了我对detach view controller 的判定。
一般来说我们呈现一个viewcontroller 里面的内容,经常采用的方式是用navigationcontroller与tabbarcontroller来管理视图控制器。在这种情况下,呈现的视图控制器都在一个app维护的控制器堆栈里面。
而有一种情况就是通过self.view addsubview:AviewController.view也可以呈现出某个视图控制器。这种情况虽然看上去跟 push的结果没什么不同,但是实际上这个被呈现的view的controller并没有在当前app的视图堆栈里,也就是所谓的
detachviewcontroller,如果你在这个分离之外的视图控制器里面做present 调用,就会出现上述问题。
所以判定是否为分离视图,就是看它是不是处在当前app的控制器堆栈里面。
显然app的 rootviewcontroller 当然是处于堆栈里,并且是堆栈最底层的视图控制器。所以这种解决方案在一定程度上是可行的。