我尝试在UIViewControllers
之间测试一些动画,在这种特殊情况下,我有一个UIViewController
,可以添加另一个UIVC
作为其子视图。
所有内容都按预期工作,子视图会被添加并显示,然后在子视图中我有一个UINavigationBar
,其左侧栏按钮有一个取消按钮(取消)。
当我点击该按钮时,我会从视图层次结构(从其父视图)触发一个尝试删除此呈现子视图的函数。
父视图中的代码:
// 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)
}
如上所示,当我单击当前按钮时,它会实例化子视图并将其设置为动画,到目前为止一直很好。
子视图代码:
// ChildViewController -> Child (ofc)
@objc func didTapCancel() {
self.willMove(toParentViewController: nil)
self.view.removeFromSuperview()
self.removeFromParentViewController()
}
现在在子视图上,当我单击取消按钮时,我知道我必须调用removeFromParentViewController()
才能正确删除它,但如果我执行了以下错误,应用程序崩溃:< / p>
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[dismissLayerTest.ChildViewController name]: unrecognized selector sent to instance 0x7fea2f60a920'
然后我尝试对self.removeFromParentViewController()
行进行评论,这样一来,应用程序就不会崩溃,但是在父视图控制器上我可以看到视图仍然附加到其父级打印self.childViewControllers.count
,它会显示1
。
你能看出问题所在吗?
由于
答案 0 :(得分:1)
我找出问题所在。
经过一些测试,我发现在使用lazy
时我们不应该使用parent-child View Controllers
实例化。
由于我将childViewController
实例化为lazy
,当我尝试将其从parentViewController
中删除时,错误说unrecognized selector sent to instance
所以我发现属性指针选择器在parentViewController
以某种方式取消分配,因为它失去了参考,因此不知道解雇的是什么孩子。
为了解决这个问题,我删除了lazy
实例化,因此它始终保持在范围内,现在我可以成功地从其父范围中删除子项。
var childViewController: ChildViewController = {
let viewController = ChildViewController()
return viewController
}()