可以玩的UI-iOS互動式動畫

weixin_34146805發表於2019-01-04

本篇通過一個例子演示CABasicAnimation 的使用,及互動式動畫的實現原理。
首先看下最終完成的效果:


2025746-d79bcf58ba54c1e5.gif
完成效果演示

頭像由矩形動畫變成圓形,整個過程可以用手指移動來控制,我們一步一步來實現它,let's GO!
首先例項一個頭像 layer:

float w = 120.0;
self.headerLayer = [CALayer layer];
self.headerLayer.frame = CGRectMake(0, 0, w, w);
self.headerLayer.position = CGPointMake((200 - w) / 2, (200 - w) / 2);
self.headerLayer.anchorPoint = CGPointMake(0, 0.5);
self.headerLayer.contents = (__bridge id)[UIImage imageNamed:@"head.jpg"].CGImage;
self.headerLayer.masksToBounds = YES;
self.headerLayer.cornerRadius = 0.0;
[self.containerView.layer addSublayer:self.headerLayer];

在這裡,裁剪圓角主要用 cornerRadius 來完成,初始化為沒有圓角。
接下來設定動畫,在動畫之前,先讓動畫暫停,否則動畫設定完後會自動播放:

self.headerLayer.speed = 0.0;

由於我們的動畫包含圓角變換,並沿著y軸平移,這兩個動畫都要在平移手勢的控制之下,我們使用組合動畫的方式來實現:

CABasicAnimation *animation = [CABasicAnimation animation];
animation.keyPath = @"cornerRadius";
animation.toValue = @(w / 2);
animation.duration = 1.0;

CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnimation.toValue = @(self.headerLayer.position.y - w);
positionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[animation, positionAnimation];
[self.headerLayer addAnimation:animaGroup forKey:@"Animation"];

最後我們設定手勢的處理:

- (void)pan:(UIPanGestureRecognizer *)pan
{
    CGFloat x = [pan translationInView:self.view].x;
    
    x /= 200.0f;
    
    CFTimeInterval timeOffset = self.headerLayer.timeOffset;
    timeOffset = MIN(0.999, MAX(0.0, timeOffset - x));
    self.headerLayer.timeOffset = timeOffset;
    self.titleLabel.layer.timeOffset = timeOffset;
    
    [pan setTranslation:CGPointZero inView:self.view];
}

手動互動的關鍵是控制 layer 的 timeOffset,它可以控制當前動畫執行的時間偏移量,範圍在0~1之間,所以我們要將移動手勢的位置和動畫的時間點做一個換算。另外注意將手勢重置,以保證每次能獲得相對於上一次的偏移位置(x)。

相關文章