我正在创建两个子视图控制器childA
和childB
,以由视图控制器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>'
这是怎么回事?如果我同时将childA
和childB
创建为我的parent
的子代,而不是子代和“孙代”,则不会出现此问题。但是我希望能够像文档中所述嵌套子视图控制器,实际上我实际上想更深入地嵌套。