ios - 从父级移除 subview Controller 时应用程序崩溃

标签 ios swift3 uiviewcontroller childviewcontroller

我正在尝试测试 UIViewControllers 之间的一些动画,在这种特殊情况下,我有一个 UIViewController 添加另一个 UIVC 作为它的 child 查看。

一切都按预期工作, subview 被添加和呈现,然后在 subview 上我有一个 UINavigationBar,它有一个取消按钮(关闭)作为它的左栏按钮。

当我点击那个按钮时,我触发了一个函数,它试图从 View 层次结构(从它的父 View )中删除这个呈现的 subview 。

来自父 View 的代码:

    // ViewController -> Parent

lazy var presentButton: UIButton = {
    let b = UIButton(type: .custom)
    b.setTitle("Present", for: .normal)
    b.setTitleColor(.black, for: .normal)
    b.addTarget(self, action: #selector(didTapPresentButton), for: .touchUpInside)
    return b
}()

lazy var childViewController: PresentedViewController = {
    let viewController = PresentedViewController()
    return viewController
}()


@objc func didTapPresentButton() {
    addViewControllerAsChildViewController(childViewController: childViewController)    
}


func addViewControllerAsChildViewController(childViewController: UIViewController) {
    self.addChildViewController(childViewController)
    childViewController.view.frame = CGRect.zero

    self.view.addSubview(childViewController.view)

    let newFrame = view.bounds
    UIView.animate(withDuration: 2) {
        childViewController.view.frame = newFrame
    }
    childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    childViewController.didMove(toParentViewController: self)
}

正如您在上面看到的,当我点击当前按钮时,它会实例化 subview 并为其添加动画,目前一切顺利。

subview 代码:

// ChildViewController -> Child (ofc)

@objc func didTapCancel() {
    self.willMove(toParentViewController: nil)
    self.view.removeFromSuperview()
    self.removeFromParentViewController()
}

现在在 subview 上,当我单击取消按钮时,我知道我必须调用 removeFromParentViewController() 才能正确删除它,但是如果我这样做,应用程序会崩溃以下错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[dismissLayerTest.ChildViewController name]: unrecognized selector sent to instance 0x7fea2f60a920'

然后我尝试注释 self.removeFromParentViewController() 行,这样做,应用程序不会崩溃,但是在父 View Controller 上我可以看到 View 仍然是通过打印 self.childViewControllers.count 附加到它的父级,它会显示 1

你能看出问题出在哪里吗?

谢谢

最佳答案

我找出问题所在。

经过一些测试,我发现我们不应该在使用parent-child View Controllers 时使用lazy 实例化。

由于我将 childViewController 实例化为 lazy 当我试图将其从 parentViewController 中删除时,错误显示 unrecognized selector sent到实例 所以我发现属性指针选择器以某种方式在 parentViewController 上被释放,它不知道要解雇哪个 child ,因为它丢失了它的引用。

为了修复它,我删除了 lazy 实例化,因此它始终保留在范围内,现在我可以成功地将子级从其父范围中删除。

var childViewController: ChildViewController = {
    let viewController = ChildViewController()
    return viewController
}()

关于ios - 从父级移除 subview Controller 时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46468485/

相关文章:

c# - Xamarin Forms iOS 应用程序在突然启动时崩溃

ios - AppDelegate.h :8:9: fatal error: 'React/RCTBridgeDelegate.h' file not found #import <React/RCTBridgeDelegate. h>

ios - Swift 3 中的 UIPickerView 和子类 Array

ios - 使用 Alamofire 4 的 eTag 支持

ios - 如何使约束适用于横向和纵向 (xcode 8.1/swift3/storyboard)

ios - Xcode 8.2.1中如何拖放一个可以自动展开满屏的UITableView

ios - 如何使两个 Collection View 出现在同一个 View Controller 上?

android - href ="tel:"和免费电话号码 (0800) 可变设备行为

iOS 7 表格 View 横向单元格宽度

ios - 搜索结果问题 - Xcode 项目