在动画期间观察 UIView 帧的变化 [英] Observing change in frame of a UIView during animation
问题描述
我想在使用 animateWithDuration:delay:options:animations:completion:
进行动画处理时观察 UIView 原点 x 坐标的变化.我想在此动画期间在粒度级别跟踪 x 坐标的变化,因为我想更改与正在动画化的视图可能接触的另一个视图的交互.我想在确切的联系点进行更改.我想了解在更高级别执行此类操作的最佳方法:
I want to observe changes to the x coordinate of my UIView's origin while it is being animated using animateWithDuration:delay:options:animations:completion:
. I want to track changes in the x coordinate during this animation at a granular level because I want to make a change in interaction to another view that the view being animated may make contact with. I want to make that change at the exact point of contact. I want to understand the best way to do something like this at a higher level:
-- 我应该在联系点的完成回调中使用 animateWithDuration:...
吗?换句话说,第一个动画会一直运行直到它到达那个 x 坐标,然后动画的其余部分发生在完成回调中?
-- Should I use animateWithDuration:...
in the completion call back at the point of contact? In other words, The first animation runs until it hits that x coordinate, and the rest of the animation takes place in the completion callback?
-- 我应该使用 NSNotification
观察者并观察 frame 属性的变化吗?这是多么准确/粒度?我可以跟踪对 x 的每次更改吗?我应该在单独的线程中执行此操作吗?
-- Should I use NSNotification
observers and observe changes to the frame property? How accurate / granular is this? Can I track every change to x? Should I do this in a separate thread?
欢迎提出任何其他建议.我正在寻找最佳实践.
Any other suggestions would be welcome. I'm looking for a abest practice.
推荐答案
使用 CADisplayLink
因为它是专门为此目的而构建的.在文档中,它说:
Use CADisplayLink
since it is specifically built for this purpose. In the documentation, it says:
一旦显示链接与运行循环相关联,当屏幕内容需要更新时,将调用目标上的选择器.
Once the display link is associated with a run loop, the selector on the target is called when the screen’s contents need to be updated.
对我来说,我有一个填满的栏,当它通过某个标记时,我不得不更改该标记上方视图的颜色.
For me I had a bar that fills up, and as it passed a certain mark, I had to change the colors of the view above that mark.
这就是我所做的:
let displayLink = CADisplayLink(target: self, selector: #selector(animationDidUpdate))
displayLink.frameInterval = 3
displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
UIView.animateWithDuration(1.2, delay: 0.0, options: [.CurveEaseInOut], animations: {
self.viewGaugeGraph.frame.size.width = self.graphWidth
self.imageViewGraphCoin.center.x = self.graphWidth
}, completion: { (_) in
displayLink.invalidate()
})
func animationDidUpdate(displayLink: CADisplayLink) {
let presentationLayer = self.viewGaugeGraph.layer.presentationLayer() as! CALayer
let newWidth = presentationLayer.bounds.width
switch newWidth {
case 0 ..< width * 0.3:
break
case width * 0.3 ..< width * 0.6:
// Color first mark
break
case width * 0.6 ..< width * 0.9:
// Color second mark
break
case width * 0.9 ... width:
// Color third mark
break
default:
fatalError("Invalid value observed. \(newWidth) cannot be bigger than \(width).")
}
}
在示例中,我将 frameInterval
属性设置为 3
,因为我不必严格更新.默认值为 1
,这意味着它会为每一帧触发,但会影响性能.
In the example, I set the frameInterval
property to 3
since I didn't have to rigorously update. Default is 1
and it means it will fire for every frame, but it will take a toll on performance.
这篇关于在动画期间观察 UIView 帧的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!