【发布时间】:2018-07-15 16:16:45
【问题描述】:
我需要导航控制器堆栈中所有控制器的可拖动视图。为了管理这个视图和手势识别器,我使用了名为 ChildViewController 的自定义 VC。在 navController 的 viewDidLoad 方法中,我添加了子控制器。在 ChildViewController 中,我在 didMoveToParent 方法中创建视图并设置约束。在手势识别器中使用约束的常数来计算平移时的视图位置。及其作品。但是每次当我在 navController 的堆栈中推送或弹出控制器时,navController 都会调用 ChildViewController 的 didMoveToParent 方法并设置约束。之后,手势识别器开始无法正常工作。我通过实现 isConstrainted 变量并在 didMoveToParent 中添加 if 语句来解决这个问题。现在,约束设置一劳永逸。但是,当我在viewDidLoad中添加一次子vc时,为什么navController在推送或弹出时调用子vc的didMoveToParent? GIF https://i.stack.imgur.com/MEeu6.gif gitHub 上的项目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
}
}
}
【问题讨论】:
标签: ios swift uiviewcontroller uinavigationcontroller uikit