Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

ios - Unified UIViewController "became frontmost" detection?

In my mind, these situations are all parallel:

  • My view controller presented another view controller fullscreen, which has now been dismissed

  • My view controller presented another view controller not fullscreen, which has now been dismissed

  • My view controller presented a popover, which has now been dismissed

  • My view controller pushed another view controller, which has now been popped

In every case, my view controller ceased to be the "frontmost" view controller, and then became "frontmost" again. I find it curious that iOS has no single blanket "became frontmost" event sent to my view controller that covers all these situations.

I think I can cover each of those cases individually, and I think those are all the cases I need to cover, but the resulting code is confusing and scattered:

  • viewDidAppear detects popping of a pushed view controller and dismissal of a fullscreen presented view controller

  • popover delegate message detect dismissal of a popover

  • not sure what detects dismissal of a nonfullscreen presented view controller

How do people handle this coherently and elegantly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What the cases have in common is not the appearance of the original view controller but the disappearance of the presented/pushed view controller. Therefore, one simple and clear solution seems to be a protocol-and-delegate architecture. Declare a pair of protocols, as follows:

protocol Home : class {
    func comingHome()
}
protocol Away : class {
    var home : Home? {get set}
}
extension Away where Self : UIViewController {
    func notifyComingHome() {
        if self.isBeingDismissed || self.isMovingFromParent {
            self.home?.comingHome()
        }
    }
}
  • The home view controller must adopt Home, and must set each view controller's home to self when it presents or pushes it.

  • The presented or pushed view controllers must adopt Away, and must implement viewWillDisappear as follows:

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.notifyComingHome()
    }
    

This works for the four cases listed in the question. It's a pity, though, that Cocoa Touch doesn't do this for you automatically.


EDIT This approach has become even more important in my apps now that iOS 13 has forced nonfullscreen presented view controllers upon us. Also, I have subclassed UIAlertController so that it conforms to Away.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...