多层present,dismiss回到首次present的控制器
2016-08-31 本文已影响1117人
gitKong
项目适应需求 : 多层present,dismiss回到首次present的控制器
例如:首页透明导航控制器,下一个控制器的导航栏非透明:
-
实现方法:
- 通过自定义转场动画,模仿push(代码实现后续补上)
- 自定义导航控制器以及NavigationBar
- 等等...(网上很多种实现方法,个人是用第一种方法实现的)
此时如果是 present 一个导航控制器,然后push,此时如果dismiss,就会回到最近的一个present控制器,如果一开始是多层present,那么此时dismiss只会回到最后present的那个控制器
A-present->B-present->C-dismiss->B
A-present->B-present->C-push->D-dismiss->C
此时需要指定回到A,就只能一层一层dismiss,会在中间的控制器停留很短暂时间,有没有办法直接回到A呢?简单来说,多层present后我需要dismiss到指定的控制器!
-
实现思路:
先解释一下两个只读属性:
presentedViewController : 被present的控制器
presentingViewController :正在presenting的控制器
比如说, 控制器A和B,[A presentViewController B animated:YES completion:nil]; 那么A相对于B就是presentingViewController,B相对于A是presentedViewController
所有的控制器的基类都是UIViewController,通过while循环,拿到正在presenting的控制器赋值给上一个正在presenting的控制器,最后用这个控制器dismiss就行
实际中我抽出了一个extension,方便使用,里面还有判断当前控制器是modal 进来 还是 push 进来
github地址 喜欢给个star呗
/**
多层present嵌套,返回到首次present的控制器
- author:孔凡列
- date: 16-09-01 02:09:03
*/
funcfl_dismissToTop() {
varviewController =selfasUIViewController
// find
while(viewController.presentingViewController!=nil) {
ifviewController.isKindOfClass(UIViewController.self) {
viewController = viewController.presentingViewController!
}
else{
break
}
}
viewController.dismissViewControllerAnimated(true, completion:nil)
}
- 用这个方法实现会出现一个不好的交互,它会显示第一个present的界面,然后dismiss,效果不太好,由于如图
慢动画播放:
3.gif- 那该如何处理呢?(😭😭测试发现,只能是连续两个present的情况才可以,间隔的present暂时没想到办法~~~哪个大神指点一下😭)
- 首先我想到的方法是 截图然后addSubView到第一个present的viewController的view中,等控制器dismiss后,最终都会一起销毁
- 还有一个方法简单很多,一进去先拿到导航控制器的navigationBar(判断后面做)以及当前viewController的view,在while循环里面判断当前控制器是否自己,如果不是,证明当前的viewController就是第一个被present的控制器啦
while (viewController.presentingViewController != nil) {
if viewController.isKindOfClass(UIViewController.self) {
if viewController != self {
viewController.view.addSubview(view)
if self.navigationController?.viewControllers.count > 1 {
viewController.view.addSubview(navBar!)
}
}
viewController = viewController.presentingViewController!
}
else {
break
}
}
viewController.dismissViewControllerAnimated(true, completion: nil)
-
实际开发中推荐使用:
首次present,后续通过push实现,此时如果要回到首页,只需要调用系统的dismiss方法就行,模仿push的present动画实现,这个具体实现会在下一篇文章中出现~~~