在使用UIView 動(dòng)畫(huà)的時(shí)候,想監(jiān)控view的一些動(dòng)畫(huà)屬性,比如frame、center 等,怎么辦呢? 也許你會(huì)說(shuō)KVO吧,你試試看,其實(shí)不行。
試想如果在繪畫(huà)周期里面獲取一次是不是可行呢, 使用CADisplayLink,它每秒固定可以執(zhí)行60次;然后每次執(zhí)行方法時(shí)在這個(gè)方法里面獲取view的展現(xiàn)層(presentationLayer)的frame。因?yàn)橹挥酗@示層發(fā)生的變化我們用戶才看得到,這時(shí)候frame才有意義。
在動(dòng)畫(huà)開(kāi)始時(shí)候啟用CADisplayLink進(jìn)行檢測(cè),動(dòng)畫(huà)結(jié)束時(shí)候停止CADisplayLink。
// 監(jiān)聽(tīng)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];
}
// 停止監(jiān)聽(tīng)MyView
- (void)stopWatchMyView {
[self.displayLink invalidate];
self.displayLink = nil;
[self watchMyViewAction];
}
- (void)handleMaskViewWithMyViewFrame:(CGRect)myFrame {
// 下面是根據(jù)myFrame 進(jìn)行其他相關(guān)view的繪制
[self.myView setNeedsDisplay];
// mask處理overlayView
self.overlayView.maskFrame = myFrame;
[self.overlayView setNeedsDisplay];
}
/////////// 觸發(fā)動(dòng)畫(huà) ///////////////
- (void)adjustMyView {
// 開(kāi)始監(jiān)控MyView,動(dòng)畫(huà)完成后停止監(jiān)控
[self startWatchMyView];
[UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.myView.frame = self.clipFrame;
} completion:^(BOOL finished) {
// 停止監(jiān)控ClipAreaView
[self stopWatchMyView];
// 調(diào)整imageView 的位置
[self adjustImageView];
}];
}
效果如下所示,裁剪框就是根據(jù)裁剪比例進(jìn)行調(diào)整了frame,其后面的遮罩view被掏空是根據(jù)這個(gè)frame 來(lái)繪制, 所以這樣就可以跟隨frame進(jìn)行動(dòng)畫(huà)了。

521985651.gif