我正在处理自定义 UIView。我让一切正常工作,但我的设计要求规定 View 的某些部分应该在加载时进行动画处理。
所以我在 didMoveToSuperview()
中调用了 UIView.animate()
,如下所示:
override func didMoveToSuperview() {
animateArrow()
}
private func animateArrow() {
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut, .autoreverse, .repeat], animations: {
self.arrowLeadingConstraint.constant += 15
self.layoutIfNeeded()
}, completion: nil)
}
我没有做任何其他事情。就其本身而言,动画只会影响我的箭头 ImageView 的前导约束。正如预期的那样,也应该如此。当我在用户交互时启动动画时,我可以验证这一点,如下图所示。
现在,问题是,当从 didMoveToSuperview()
中调用时,动画会以某种方式影响我的自定义 UIView 的所有 subview ...
我做错了什么?
最佳答案
看来问题出在您的 animateArrow()
方法本身,如果您稍微修改一下方法,例如这个:
private func animateArrow() {
self.layoutIfNeeded()
self.arrowLeadingConstraint.constant = 31 // = 15 + 16 from your original code
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut, .autoreverse, .repeat], animations: {
self.layoutIfNeeded()
}, completion: nil)
}
tada,动画将按您的预期正常运行。
为什么...?
我的解释可能不是学术性的,但我希望它对读者有帮助,以便更好地理解。
因此,简而言之,当您处理约束时,您实际上是在隐式地处理一组预定义的 View 与其周围环境之间的关系。这就是为什么您不能成功地为单个约束设置动画(您最初的尝试),因为在此上下文中只有这些关系是可动画的——而不是约束。
因此,您只能为所有关系的更新设置动画在您为布局定义了新的约束之后——原则上是在幕后可以一次性为您为每个受影响的 View 的框架制作动画。
您可以阅读更多关于约束是什么以及评估如何与自动布局一起工作的信息 from Apple ,如果您对此感兴趣的话。
关于ios - didMoveToSuperview 中调用的 UIView.animate 意外影响所有 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55723421/