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

項(xiàng)目適應(yīng)需求 : 多層present,dismiss回到首次present的控制器

例如:首頁透明導(dǎo)航控制器,下一個(gè)控制器的導(dǎo)航欄非透明:

  • 實(shí)現(xiàn)方法:

  1. 通過自定義轉(zhuǎn)場動(dòng)畫,模仿push(代碼實(shí)現(xiàn)后續(xù)補(bǔ)上)
  2. 自定義導(dǎo)航控制器以及NavigationBar
  3. 等等...(網(wǎng)上很多種實(shí)現(xiàn)方法,個(gè)人是用第一種方法實(shí)現(xiàn)的)

此時(shí)如果是 present 一個(gè)導(dǎo)航控制器,然后push,此時(shí)如果dismiss,就會(huì)回到最近的一個(gè)present控制器,如果一開始是多層present,那么此時(shí)dismiss只會(huì)回到最后present的那個(gè)控制器

A-present->B-present->C-dismiss->B

A-present->B-present->C-push->D-dismiss->C

此時(shí)需要指定回到A,就只能一層一層dismiss,會(huì)在中間的控制器停留很短暫時(shí)間,有沒有辦法直接回到A呢?簡單來說,多層present后我需要dismiss到指定的控制器!

  • 實(shí)現(xiàn)思路:

先解釋一下兩個(gè)只讀屬性:

presentedViewController : 被present的控制器

presentingViewController :正在presenting的控制器

比如說, 控制器A和B,[A presentViewController B animated:YES completion:nil]; 那么A相對(duì)于B就是presentingViewController,B相對(duì)于A是presentedViewController

所有的控制器的基類都是UIViewController,通過while循環(huán),拿到正在presenting的控制器賦值給上一個(gè)正在presenting的控制器,最后用這個(gè)控制器dismiss就行

實(shí)際中我抽出了一個(gè)extension,方便使用,里面還有判斷當(dāng)前控制器是modal 進(jìn)來 還是 push 進(jìn)來

github地址 喜歡給個(gè)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)

}

  • 用這個(gè)方法實(shí)現(xiàn)會(huì)出現(xiàn)一個(gè)不好的交互,它會(huì)顯示第一個(gè)present的界面,然后dismiss,效果不太好,由于如圖
2.gif

慢動(dòng)畫播放:

3.gif
  • 那該如何處理呢?(????測(cè)試發(fā)現(xiàn),只能是連續(xù)兩個(gè)present的情況才可以,間隔的present暫時(shí)沒想到辦法~~~哪個(gè)大神指點(diǎn)一下??)
    • 首先我想到的方法是 截圖然后addSubView到第一個(gè)present的viewController的view中,等控制器dismiss后,最終都會(huì)一起銷毀
    • 還有一個(gè)方法簡單很多,一進(jìn)去先拿到導(dǎo)航控制器的navigationBar(判斷后面做)以及當(dāng)前viewController的view,在while循環(huán)里面判斷當(dāng)前控制器是否自己,如果不是,證明當(dāng)前的viewController就是第一個(gè)被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)

  • 實(shí)際開發(fā)中推薦使用:

首次present,后續(xù)通過push實(shí)現(xiàn),此時(shí)如果要回到首頁,只需要調(diào)用系統(tǒng)的dismiss方法就行,模仿push的present動(dòng)畫實(shí)現(xiàn),這個(gè)具體實(shí)現(xiàn)會(huì)在下一篇文章中出現(xiàn)~~~

  • 總結(jié)

    1.如果可以接受上面代碼一出現(xiàn)的交互問題,而且是多層present嵌套,可以用代碼一
    2.如果不能接受上面代碼一出現(xiàn)的問題,并且只有兩層present且連續(xù)的,可以用代碼二
    3.如果都不能接受,我暫時(shí)處理不了??,推薦使用首次present,后續(xù)push,期待下一篇自定義轉(zhuǎn)場吧
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容