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

項目適應需求 : 多層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,期待下一篇自定義轉場吧
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容