showViewController:sender 的相反程序是啥:

Posted

技术标签:

【中文标题】showViewController:sender 的相反程序是啥:【英文标题】:Whats the programmatic opposite of showViewController:sender:showViewController:sender 的相反程序是什么: 【发布时间】:2014-09-09 11:00:34 【问题描述】:

我正在编写一个仅限 ios 8 的应用程序,并且我正在使用新的自适应演示文稿,它结合了“显示”和“显示详细信息”segue 以及 showViewController:sender:showDetailViewController:sender: 方法。

我的问题是调用showViewController:sender: 后返回的编程方式是什么?视图控制器的显示方式取决于其父上下文。例如。在 UINavigationController showViewController:sender: 中将一个新控制器推送到导航堆栈上,但如果视图控制器图中没有 UIKit 容器,那么 showViewController:sender: 最终会改为进行演示。

考虑到我可以编写自己的任意容器控制器,检查似乎不可行

if (self.navigationController) 
    [self.navigationController popViewControllerAnimated:YES];

else if (self.presentingViewController)
...
else if ([self.parentViewController isKindOfClass:[CrazyCustomContainer class]])
    [self.parentViewController someWackyUnwindMethod];

...

等等...那么有没有一种通用的方法来反转显示?如果不是我看到的唯一解决方案是对所有内容使用展开segues。不太麻烦,但我很好奇。

【问题讨论】:

我认为部分原因是因为对于模型,您将有一个取消按钮并调用普通的dismissViewControllerAnimated:,而对于导航控制器,它将有一个内置的后退按钮。因此,您不必经常像处理演示文稿一样处理解雇。 但这就是我的观点:showViewController: 可以进行推送或演示。呈现的视图控制器不应该知道它是如何在屏幕上显示的,所以在呈现的时候做类似[self.navigationController popViewControllerAnimated:] 这样的事情是不好的,如果它有时会因为你被呈现而失败...... 对于一个不需要弹出的导航控制器。它会有一个背部。 【参考方案1】:

Programming iOS 8: Dive Deep into Views, View Controllers, and Frameworks 中有一章介绍 showViewController:sender:showDetailViewController:sender: 如何工作。

当这些方法被调用时,它们会在自己身上调用targetViewControllerForAction:sender:,并在返回的对象上调用这个方法。然后目标对象可以以适当的方式显示视图控制器。例如,导航控制器将视图控制器推送到其导航堆栈中。

因此您可以创建一个通用的dismissVC: 方法并在不同的UIViewController 子类中覆盖它。

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()
    

这样,当您调用dismissVC: 方法时,if 将始终根据上下文正确关闭视图控制器。

【讨论】:

因此,基于此,对“是否存在与showViewController:sender: 相反的程序化问题”的实际答案?是。您必须使用 Apple 用于进行自适应演示的相同底层机制有效地实现您自己的通用版本。 是的,就是这样。虽然在这个问题中我有点在寻找一种程序化的替代方案来替代 unwind segues,这也需要代码来支持它们。这个答案 100% 满足我的要求。【参考方案2】:

这是我在 showViewController 存在之前使用的一个技巧,可能会有所帮助。

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

基本上你检查你在哪里。然后,您可以将任何保存代码放入viewDidDisappear 或类似的东西,因为它适用于两者。另一种选择是检查presentationViewController,但这并不总能保证模态显示。

【讨论】:

以上是关于showViewController:sender 的相反程序是啥:的主要内容,如果未能解决你的问题,请参考以下文章