关闭呈现的 VC 时呈现视图控制器会丢失子视图

Posted

技术标签:

【中文标题】关闭呈现的 VC 时呈现视图控制器会丢失子视图【英文标题】:Presenting View Controller loses subviews when dismissing presented VC 【发布时间】:2016-01-02 14:12:21 【问题描述】:

我在玩两个以直接方式交互的视图控制器时遇到了一些麻烦:

homeViewController 显示一个待办事项列表,带有一个 addTask 按钮。 addTask 按钮将启动一个额外的 viewController,它充当用户填写的“表单”。

但是,在调用时

 self.dismissViewControllerAnimated(true, completion: nil);

呈现的视图控制器中,我回到了我的主页,但它是空白的,除了可以看到情节提要上的***别视图(即覆盖整个屏幕)。

我所有的视图、场景等都在情节提要中设置了自动布局。我在 Stack Overflow 上环顾四周,这导致我玩弄自动调整大小的子视图参数,即:

self.view.autoresizesSubviews = false;

无济于事。我要么修复了错误的自动调整大小参数(在错误的兴趣视图中,或者只是将其设置错误),要么有其他问题。

提前致谢

编辑:

我将 VC 介绍如下:

    func initAddNewTaskController()
    let addNewTaskVC = self.storyboard?.instantiateViewControllerWithIdentifier("AddNewTaskViewController") as! AddNewTaskViewController;
    self.presentViewController(addNewTaskVC, animated: true, completion: nil);

编辑2:

虽然我接受使用委托或展开 segue 确实可以规避我遇到的问题(正如 campbell_souped 所建议的那样),但我仍然不明白当我关闭导致空白屏幕的视图控制器时从根本上发生了什么。

我知道调用dismissViewControllerAnimated 会传递到呈现视图控制器(在本例中是我的homeViewController)。由于我不需要进行任何解雇前或解雇后的配置,因此(在我看来)这里不需要使用委托。

我目前的想法是,由于某种原因,当我调用

dismissViewControllerAnimated(true, completion:nil);

在我的 addNewTaskViewController 中,它实际上是在释放我的 homeViewController。我希望有人能告诉我究竟是什么我不了解视图控制器是如何呈现/关闭的。

【问题讨论】:

你能展示你将控制器呈现为“表单”的方式吗? 已编辑原帖;使用自动布局构建的 UI;不使用委托模式 【参考方案1】:

在这种情况下,我通常采取两条路线之一。要么在AddNewTaskViewController 上设置一个代理,要么使用展开转场。

使用委托方法,设置协议:

protocol AddNewTaskViewControllerDelegate 
    func didDismissNewTaskViewControllerWithSuccess(success: Bool)

AddNewTaskViewController 中添加一个代表委托的可选属性

var delegate: AddNewTaskViewControllerDelegate?

然后在您要关闭AddNewTaskViewController 时调用didDismissNewTaskViewControllerWithSuccess

如果记录添加成功:

self.delegate?.didDismissNewTaskViewControllerWithSuccess(true)
self.dismissViewControllerAnimated(true, completion: nil);

或者如果有取消/失败:

self.delegate?.didDismissNewTaskViewControllerWithSuccess(false)
self.dismissViewControllerAnimated(true, completion: nil);

最后,将自己设置为代理,修改之前的 sn-p:

func initAddNewTaskController()
    let addNewTaskVC = self.storyboard?.instantiateViewControllerWithIdentifier("AddNewTaskViewController") as! AddNewTaskViewController;
    self.presentViewController(addNewTaskVC, animated: true, completion: nil);

到这里:

    func initAddNewTaskController() 
        guard let addNewTaskVC = self.storyboard?.instantiateViewControllerWithIdentifier("AddNewTaskViewController") as AddNewTaskViewController else  return 
        addNewTaskVC.delegate = self
        self.presentViewController(addNewTaskVC, animated: true, completion: nil);
    

    ...


// MARK: AddNewTaskViewControllerDelegate
extension homeViewController: AddNewTaskViewControllerDelegate 

    func didDismissNewTaskViewControllerWithSuccess(success: Bool) 
        if success 
            self.tableView.reloadData()
        
    


[ 扩展名在您的homeViewController 类之外]

使用 unwind segue 方法,看看这个 Ray Wenderlich 示例: http://www.raywenderlich.com/113394/storyboards-tutorial-in-ios-9-part-2

此方法涉及从 IBAction 按住 Ctrl 键拖动到视图控制器上方的退出对象,然后从弹出菜单中选择正确的操作名称

【讨论】:

感谢您的回答!我的另一个问题是使用委托来执行此操作或缺少委托之间的根本区别是什么? 简单地说,委托模式更加健壮。您可以向didDismissNewTaskViewControllerWithSuccess 函数添加其他函数,甚至添加更多参数。 您知道通过简单地关闭视图控制器可能导致我的问题的原因吗? 您是要取消homeViewController 还是AddNewTaskViewController 我怎么知道我要解雇哪一个? func 不接受视图控制器作为输入,从它的文档来看,我应该取消 AddNewTaskViewController,因为它(至少我认为它是)明确地是唯一已呈现的视图控制器

以上是关于关闭呈现的 VC 时呈现视图控制器会丢失子视图的主要内容,如果未能解决你的问题,请参考以下文章

在呈现新视图控制器后关闭当前视图控制器 - swift

UIDocumentMenuViewController 关闭呈现视图控制器

根视图控制器呈现的两个视图控制器之间的转换

关闭呈现的视图控制器后调用主控制器的函数

如何在模态呈现的视图控制器上执行呈现模态序列?

如何正确呈现视图控制器?