我正试图对一个简单的自动布局约束进行动画改变,但当我第一次调用它时,它就会产生动画,但不是仅仅拉伸和改变高度,而是将整个视图向上移动,如果我再次调用它,它就会自行修复。
这是我如何设置约束条件的。
hiddenView.addSubview(topView)
topView.translatesAutoresizingMaskIntoConstraints = false
topView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
topView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
topView.bottomAnchor.constraint(equalTo: hiddenView.bottomAnchor).isActive = true
topViewDefaultTopAnchorConstraints.append(topView.topAnchor.constraint(equalTo: hiddenView.centerYAnchor))
topViewSelectedTopAnchorConstraints.append(topView.topAnchor.constraint(equalTo: hiddenView.topAnchor))
NSLayoutConstraint.activate(topViewDefaultTopAnchorConstraints)
下面是我更新它们的方法
func showTopView() {
NSLayoutConstraint.deactivate(topViewDefaultTopAnchorConstraints)
NSLayoutConstraint.activate(topViewSelectedTopAnchorConstraints)
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
更新: 这里是一个gif图,显示了当我调用 showTopView
,再次调用它可以修复底部约束。
它应该像第二张图一样,只是向上做动画,而不是把整个视图都带起来,就像第二张图一样。bottomAnchor
不变,我该如何解决这个问题?
更新:我意识到,我把下面的 topView
和 bottomView
如果我不把顶角磨圆,那么它就能正常工作,所以它和这个有关系。
override func viewDidLayoutSubviews() {
topView.roundCorners(corners: [.topLeft, .topRight], radius: 100*ScreenDimensions.ASPECT_RATIO_RESPECT_OF_XMAX)
bottomView.roundCorners(corners: [.topLeft, .topRight], radius: 100*ScreenDimensions.ASPECT_RATIO_RESPECT_OF_XMAX)
topConstraint = topView.topAnchor.constraint(equalTo: hiddenView.topAnchor, constant: hiddenView.frame.height/2)
topConstraint.isActive = true
}
好像是 hiddenView
's bottomAnchor
被拉起的同时 topView
的底部在这里。确保 hiddenView
'的bottomAnchor受到了适当的约束。而更好的方法是提供一个叫做 heightAnchor
并增加heightConstraint的常量值,以使视图增加高度的动画。
我想我知道你的问题是什么。你可能需要使用常量,而不是定义了两个不同的约束,你激活了它。
var topConstraint: NSLayoutConstraint!
然后,初始化它,如下图所示。
hiddenView.addSubview(topView)
topView.translatesAutoresizingMaskIntoConstraints = false
topView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
topView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
topView.bottomAnchor.constraint(equalTo: hiddenView.bottomAnchor).isActive = true
topConstraint = topView.topAnchor.constraint(equalTo: hiddenView.topAnchor, constant: hiddenView.frame.height/2)
topConstraint.isActive = true
然后在showTopView里面,你只需要更新常量,就能创建你想要的动画。
func showTopView() {
topConstraint.isActive = false
topConstraint.constant = 0
topConstraint.isActive = true
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
同样的,如果你想把视图恢复到正常状态,你会按照下面的方法实现。
func hideTopView() {
topConstraint.isActive = false
topConstraint.constant = hiddenView.frame.height/2
topConstraint.isActive = true
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
}
你用这种方法可能会更幸运。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let r = 100*ScreenDimensions.ASPECT_RATIO_RESPECT_OF_XMAX
topView.layer.cornerRadius = r
topView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
bottomView.layer.cornerRadius = r
bottomView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}