美文网首页ios 知识点iOS开发小技巧iOS学习
多层present,dismiss回到首次present的控制器

多层present,dismiss回到首次present的控制器

作者: gitKong | 来源:发表于2016-08-31 14:34 被阅读1117次

项目适应需求 : 多层present,dismiss回到首次present的控制器

例如:首页透明导航控制器,下一个控制器的导航栏非透明:

  • 实现方法:

  1. 通过自定义转场动画,模仿push(代码实现后续补上)
  2. 自定义导航控制器以及NavigationBar
  3. 等等...(网上很多种实现方法,个人是用第一种方法实现的)

此时如果是 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,效果不太好,由于如图
2.gif

慢动画播放:

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动画实现,这个具体实现会在下一篇文章中出现~~~

  • 总结

    1.如果可以接受上面代码一出现的交互问题,而且是多层present嵌套,可以用代码一
    2.如果不能接受上面代码一出现的问题,并且只有两层present且连续的,可以用代码二
    3.如果都不能接受,我暂时处理不了😭,推荐使用首次present,后续push,期待下一篇自定义转场吧

相关文章

网友评论

    本文标题:多层present,dismiss回到首次present的控制器

    本文链接:https://www.haomeiwen.com/subject/sjbqettx.html