在使用UIView 动画的时候,想监控view的一些动画属性,比如frame、center 等,怎么办呢? 也许你会说KVO吧,你试试看,其实不行。
试想如果在绘画周期里面获取一次是不是可行呢, 使用CADisplayLink,它每秒固定可以执行60次;然后每次执行方法时在这个方法里面获取view的展现层(presentationLayer)的frame。因为只有显示层发生的变化我们用户才看得到,这时候frame才有意义。
在动画开始时候启用CADisplayLink进行检测,动画结束时候停止CADisplayLink。
// 监听MyView
- (void)startWatchMyView {
[self stopWatchMyView];
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(watchMyViewAction)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)watchMyViewAction {
CALayer *presentationLayer = self.myView.layer.presentationLayer;
[self handleMaskViewWithMyViewFrame:presentationLayer.frame];
}
// 停止监听MyView
- (void)stopWatchMyView {
[self.displayLink invalidate];
self.displayLink = nil;
[self watchMyViewAction];
}
- (void)handleMaskViewWithMyViewFrame:(CGRect)myFrame {
// 下面是根据myFrame 进行其他相关view的绘制
[self.myView setNeedsDisplay];
// mask处理overlayView
self.overlayView.maskFrame = myFrame;
[self.overlayView setNeedsDisplay];
}
/////////// 触发动画 ///////////////
- (void)adjustMyView {
// 开始监控MyView,动画完成后停止监控
[self startWatchMyView];
[UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.myView.frame = self.clipFrame;
} completion:^(BOOL finished) {
// 停止监控ClipAreaView
[self stopWatchMyView];
// 调整imageView 的位置
[self adjustImageView];
}];
}
网友评论