在动画期间观察 UIView 帧的变化 [英] Observing change in frame of a UIView during animation

查看:28
本文介绍了在动画期间观察 UIView 帧的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆