Whats the programmatic opposite of showViewController:sender:

╄→尐↘猪︶ㄣ 提交于 2019-12-20 09:10:04

问题


I'm writing an iOS 8 only app and I'm using the new adaptive presentations using a combination of the "Show" and the "Show Detail" segue and the showViewController:sender: and showDetailViewController:sender: methods.

My question is what is the programatic way to go back after calling showViewController:sender:? The way the view controller is shown depends on its parent context. E.g. in a UINavigationController showViewController:sender: pushes a new controller onto the navigation stack but if there is no UIKit container in the view controller graph then showViewController:sender: ends up doing a presentation instead.

Considering i could write my own arbitrary container controller it seems unfeasible to check

if (self.navigationController) {
    [self.navigationController popViewControllerAnimated:YES];
}
else if (self.presentingViewController){
...
else if ([self.parentViewController isKindOfClass:[CrazyCustomContainer class]]){
    [self.parentViewController someWackyUnwindMethod];
}
...

etc... so is there a generic way to reverse being shown? If not the only solution i see is to use unwind segues for everything. Not too much of a hassle but I'm curious.


回答1:


There is a chapter on how showViewController:sender: and showDetailViewController:sender: work in Programming iOS 8: Dive Deep into Views, View Controllers, and Frameworks.

When these methods are called, they call targetViewControllerForAction:sender: on themselves and call this method on the returned object. The target object can then display the view controller in an appropriate way. For example, a navigation controller pushes the view controller on its navigation stack.

So you can create a generic dismissVC: method and override it in different UIViewController subclasses.

extension UIViewController {
    func dismissVC(sender:AnyObject?) {
        if let presentingVC = targetViewControllerForAction("dismissVC", withSender: sender) as? UIViewController {
            presentingVC.dismissVC(self)
        }
    }
}

extension UINavigationController {
    override func dismissVC(sender: AnyObject?) {
        popViewControllerAnimated(true)
    }
}

extension CrazyCustomContainer {
    override func dismissVC(sender: AnyObject?) {
        someWackyUnwindMethod()
    }
}

This way, when you call dismissVC: method, if will always correctly dismiss the view controller depending on the context.




回答2:


Here is a trick I've used before showViewController existed that may help.

if let nav = navigationController {
    // We have a navigation controller so we'll have a back button
}
else {
    // no navigation controller, need a cancel button
    // ... Add Cancel Button
}

Basically you check for where you're at. Then after that you can put any save code in viewDidDisappear or something like that for it work for both. Another option is to check for presentationViewController but this doesn't always guarantee modal presentation.



来源:https://stackoverflow.com/questions/25742944/whats-the-programmatic-opposite-of-showviewcontrollersender

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!