【发布时间】:2016-02-22 06:48:38
【问题描述】:
我有一个自定义 UIView,它使用 UIKit Dynamics 在用户点击按钮时执行动画。有问题的视图很简单,我在layoutSubviews() 中手动布局。然而,在 UIKit Dynamics 运行时,每帧动画都会调用 layoutSubviews(),而我在此期间所做的任何布局更改(例如,响应更高的状态栏)都会导致我的动态视图失真。
如何在 UIKit Dynamics 动画进行时响应视图大小的变化?
更新
我创建了一个演示项目(它与我的用例非常匹配,尽管它被精简了),并将其发布到on GitHub。故事板使用 AutoLayout,但视图选择退出 AutoLayout 以使用 translatesAutoresizingMaskIntoConstraints = false 布置自己的子视图。要重现该行为,请在模拟器中运行(我选择 iPhone 5),然后在星星摆动时按 ⌘Y 以见证失真。这是视图代码:
import UIKit
class CustomView: UIView {
var swingingView: UIView!
var animator: UIDynamicAnimator!
var attachment: UIAttachmentBehavior!
var lastViewFrame = CGRectZero
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.translatesAutoresizingMaskIntoConstraints = false
swingingView = UIImageView(image: UIImage(named: "Star"))
self.addSubview(swingingView)
}
override func layoutSubviews() {
// Don't run for every frame of the animation. Only when responding to a layout change
guard self.frame != lastViewFrame else {
return
}
lastViewFrame = self.frame
swingingView.frame = CGRect(x: 0, y: self.frame.size.height / 2, width: 100, height: 100)
// Only run this setup code once
if animator == nil {
animator = UIDynamicAnimator(referenceView: self)
let gravity = UIGravityBehavior(items: [swingingView])
gravity.magnitude = 1.5
animator.addBehavior(gravity)
attachment = UIAttachmentBehavior(item: swingingView,
offsetFromCenter: UIOffset(horizontal: 0, vertical: swingingView.frame.size.height / -2),
attachedToAnchor: CGPoint(x: self.bounds.size.width / 2, y: 0))
attachment.length = CGFloat(250.0)
animator.addBehavior(attachment)
}
animator.updateItemUsingCurrentState(swingingView)
}
}
【问题讨论】:
-
您是否尝试过创建
UIViewController的自定义实例并将动画和布局放入viewDidLoad()中?这将解决您的布局代码被多次触发的问题。 -
你能把代码放在这里吗?我认为可能发生的事情是您的 autoLayout 是基于您的动画视图,因此当它动画时,会调用 updateConstraints 并且它会根据动画扭曲您的视图。如果是这种情况,请确保您的其他视图约束基于布局指南边距而不是动画视图
-
好吧,如果您使用变量来设置帧,我想最好的办法是调试。也许在
layoutSubviews()中设置帧的位置设置断点,然后查看哪些值正在发生变化。恐怕没有代码我帮不上什么忙。 -
@MatthewLawrenceBailey 我在问题中添加了一个代码示例,并在 GitHub 上添加了一个完整项目:github.com/abbeycode/LayoutDuringDynamics
标签: ios swift user-interface layout uikit-dynamics