我需要在导航控制器堆栈中所有控制器上的可拖动视图。为了管理该视图和手势识别器,我使用了称为VC的自定义VC。在navController的viewDidLoad方法中,我添加了子控制器。在ChildViewController中,我创建了视图并在didMoveToParent方法中设置了约束。在手势识别器中使用约束常量来计算平移时的视图位置。及其作品。但是每次当我在navController的堆栈中推入或弹出控制器时,navController都会使用约束设置调用ChildViewController的didMoveToParent方法。之后,该手势识别器将无法正常工作。我通过实现isConstrainted变量并在didMoveToParent中添加if语句来解决此问题。现在,约束设置一劳永逸。但是,当我在viewDidLoad中一次添加子vc时,为什么在推入或弹出时navController会调用子vc的didMoveToParent? gitHub https://i.stack.imgur.com/MEeu6.gif上的GIF https://github.com/ayatsev/ChildNavController项目
class CustomNavController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
let childController = ChildViewController()
addChild(childController)
view.addSubview(childController.view)
childController.didMove(toParent: self)
}
}
class ChildViewController: UIViewController {
var xConstraint: NSLayoutConstraint!
var yConstraint: NSLayoutConstraint!
var isConstrainted = false
lazy var childView: UIView = {
let cv = UIView()
cv.translatesAutoresizingMaskIntoConstraints = false
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
cv.addGestureRecognizer(panRecognizer)
cv.backgroundColor = .green
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
view = childView
}
override func didMove(toParent parent: UIViewController?) {
print("--- CHILD: Did Move To Parent")
guard let parent = parent else {return}
if !isConstrainted {
childView.widthAnchor.constraint(equalToConstant: 50).isActive = true
childView.heightAnchor.constraint(equalToConstant: 50).isActive = true
xConstraint = childView.leadingAnchor.constraint(equalTo: parent.view.leadingAnchor, constant: 40)
xConstraint.isActive = true
yConstraint = childView.topAnchor.constraint(equalTo: parent.view.topAnchor, constant: parent.view.frame.height * 2 / 3)
yConstraint.isActive = true
isConstrainted = true
}
}
@objc func handlePan(recognizer: UIPanGestureRecognizer) {
guard let parent = parent else {return}
let translation = recognizer.translation(in: parent.view)
switch recognizer.state {
case .changed:
xConstraint.constant += translation.x
yConstraint.constant += translation.y
recognizer.setTranslation(CGPoint.zero, in: parent.view)
default:
break
}
}
}
答案 0 :(得分:0)
但是为什么在推入或弹出时navController调用子vc的didMoveToParent
毫无疑问要问“为什么”。这就是系统的工作方式。有时didMove(toParent:)
到达时没有相应的willMove(toParent:)
。有时didMove(toParent:)
到达,即使此视图控制器以前是该父级的子级,而仍是该父级的子级。我知道这似乎很疯狂。但是,您不必理会原因,而应该以对收到的消息做出一致响应的方式进行编码。