sam*_*ous 11 animation uiview ios observer-pattern
我想观察UIView原点的x坐标在使用动画时的变化animateWithDuration:delay:options:animations:completion:.我想在粒度级别跟踪此动画期间x坐标的变化,因为我想在交互中更改另一个视图,即动画视图可能与之接触.我想在确切的联系点做出改变.我想了解在更高层次上做这样的事情的最佳方法:
- 我应该animateWithDuration:...在联系点的完成回电中使用吗?换句话说,第一个动画一直运行直到它到达那个x坐标,其余的动画发生在完成回调中?
- 我应该使用NSNotification观察者并观察框架属性的变化吗?这有多准确/精细?我可以跟踪x的每个变化吗?我应该在一个单独的线程中这样做吗?
欢迎任何其他建议.我正在寻找一个很好的练习.
fun*_*ct7 14
使用,CADisplayLink因为它是专门为此目的而构建的.在文档中,它说:
一旦显示链接与运行循环相关联,当需要更新屏幕内容时,将调用目标上的选择器.
对我来说,我有一个填满的酒吧,当它通过一定的标记时,我不得不改变那个标记上方的视图的颜色.
这就是我做的:
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).")
}
}
Run Code Online (Sandbox Code Playgroud)
在示例中,我将frameInterval属性设置为,3因为我不必严格更新.默认值是1,它意味着它将为每一帧触发,但它会对性能产生影响.
NSTimer在每次失效后创建一个延迟并运行特定选择器.
在该方法中,检查动画视图的框架并将其与碰撞视图进行比较.
并确保使用presentationLayer框架, 因为如果在动画时访问view.frame,它会给出在动画中不变的目标框架.
CGRect animationViewFrame= [[animationView.layer presentationLayer] frame];
Run Code Online (Sandbox Code Playgroud)
如果你不想创建计时器,write a selector which calls itself after some delay.延迟大约.01秒.
澄清 - >
假设您有一个视图,您可以将其位置从(0,0)设置为(100,100),持续时间为5秒.假设您将KVO实现到此视图的框架
当您调用时animateWithDuration block,视图的位置会直接更改为(100,100),这是最终值,即使视图以中间位置值移动也是如此.
因此,您的KVO将在动画开始的瞬间被解雇一次.因为,图层有layer Tree和Presentation Tree.虽然layer tree只存储目的地值而presentation Layer存储中间值.
当您访问view.frame它时,它将始终给出帧的值而layer tree不是它所采用的中间帧.
所以,你必须presentation Layer frame用来获得中间帧.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
4583 次 |
| 最近记录: |