如何监听动画中view的frame

在使用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];
    }];
}

效果如下所示,裁剪框就是根据裁剪比例进行调整了frame,其后面的遮罩view被掏空是根据这个frame 来绘制, 所以这样就可以跟随frame进行动画了。

如何监听动画中view的frame_第1张图片
521985651.gif

你可能感兴趣的:(如何监听动画中view的frame)