嵌套子UIViewControllers时最终崩溃

时间:2019-11-21 00:26:07

标签: ios swift uiviewcontroller nested childviewcontroller

我正在创建两个子视图控制器childAchildB,以由视图控制器parent显示和管理。我希望掌握嵌套子控制器的工作方式,但现在最终会崩溃。

我创建了UIViewController的通用扩展,以帮助我添加子控制器:

@nonobjc public extension UIViewController {

    func addChildController(_ child: UIViewController, frame: CGRect? = nil) {
        addChild(child)
        if let frame = frame {
            child.view.frame = frame
        }
        view.addSubview(child.view)
        child.didMove(toParent: self)
    }
}

我从添加一个子控制器的父控制器开始,当我按下“预览”按钮时就会显示该子控制器:

class ParentViewController: UIViewController {

    lazy var childA = ChildAViewController(nibName: "ChildAViewController", bundle: nil)

    override func viewDidLoad() {
        super.viewDidLoad()
        addChildController(childA, frame: view.bounds)
    }

    @IBAction func preview(_ sender: Any) {
        childA.view.isHidden = false
    }
}

childA控制器又添加了自己的子控制器childB。这些控制器视图中的每个视图上都有按钮可以在它们之间来回切换。

class ChildAViewController: UIViewController {

    lazy var childB = ChildBViewController(nibName: "ChildBViewController", bundle: nil)

    override func viewDidLoad() {
        super.viewDidLoad()
        view.isHidden = true

        addChildController(childB, frame: view.bounds)
        childB.childA = self
    }

    @IBAction func showChildBView(_ sender: Any) {
        childB.view.isHidden = false
        let transitionOptions: UIView.AnimationOptions = [.transitionFlipFromRight]
        UIView.transition(from: view, to: childB.view, duration: 1, options: transitionOptions) { success in
            self.view.isHidden = true
        }
    }
}


class ChildBViewController: UIViewController {

    var childA: ChildAViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.isHidden = true
    }

    @IBAction func showChildAView(_ sender: Any) {
        childA!.view.isHidden = false
        let transitionOptions: UIView.AnimationOptions = [.transitionFlipFromRight]
        UIView.transition(from: view, to: childA!.view, duration: 1, options: transitionOptions) { success in
            self.view.isHidden = true
        }
    }
}

奇怪的是,我可以来回翻转,先显示A,然后显示B,然后再显示A,但是随后当再次显示B时,应用突然崩溃,并出现以下错误:

2019-11-20 16:09:19.984575-0800 MyApp[95630:6863114] *** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<MyApp.ChildBController: 0x7fb05a03b200> should have parent view controller:<MyApp.ParentController: 0x7fb05945bf10> but actual parent is:<MyApp.ChildAController: 0x7fb05a074e00>'

这是怎么回事?如果我同时将childAchildB创建为我的parent的子代,而不是子代和“孙代”,则不会出现此问题。但是我希望能够像文档中所述嵌套子视图控制器,实际上我实际上想更深入地嵌套。

0 个答案:

没有答案