9.3 手動動畫

2018-02-24 15:07 更新

手動動畫

timeOffset一個很有用的功能在于你可以它可以讓你手動控制動畫進程,通過設(shè)置speed為0,可以禁用動畫的自動播放,然后來使用timeOffset來來回顯示動畫序列。這可以使得運用手勢來手動控制動畫變得很簡單。

舉個簡單的例子:還是之前關(guān)門的動畫,修改代碼來用手勢控制動畫。我們給視圖添加一個UIPanGestureRecognizer,然后用timeOffset左右搖晃。

因為在動畫添加到圖層之后不能再做修改了,我們來通過調(diào)整layertimeOffset達到同樣的效果(清單9.4)。

清單9.4 通過觸摸手勢手動控制動畫

@interface ViewController ()

@property (nonatomic, weak) UIView *containerView;
@property (nonatomic, strong) CALayer *doorLayer;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //add the door
    self.doorLayer = [CALayer layer];
    self.doorLayer.frame = CGRectMake(0, 0, 128, 256);
    self.doorLayer.position = CGPointMake(150 - 64, 150);
    self.doorLayer.anchorPoint = CGPointMake(0, 0.5);
    self.doorLayer.contents = (__bridge id)[UIImage imageNamed:@"Door.png"].CGImage;
    [self.containerView.layer addSublayer:self.doorLayer];
    //apply perspective transform
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0 / 500.0;
    self.containerView.layer.sublayerTransform = perspective;
    //add pan gesture recognizer to handle swipes
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] init];
    [pan addTarget:self action:@selector(pan:)];
    [self.view addGestureRecognizer:pan];
    //pause all layer animations
    self.doorLayer.speed = 0.0;
    //apply swinging animation (which won't play because layer is paused)
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform.rotation.y";
    animation.toValue = @(-M_PI_2);
    animation.duration = 1.0;
    [self.doorLayer addAnimation:animation forKey:nil];
}

- (void)pan:(UIPanGestureRecognizer *)pan
{
    //get horizontal component of pan gesture
    CGFloat x = [pan translationInView:self.view].x;
    //convert from points to animation duration //using a reasonable scale factor
    x /= 200.0f;
    //update timeOffset and clamp result
    CFTimeInterval timeOffset = self.doorLayer.timeOffset;
    timeOffset = MIN(0.999, MAX(0.0, timeOffset - x));
    self.doorLayer.timeOffset = timeOffset;
    //reset pan gesture
    [pan setTranslation:CGPointZero inView:self.view];
}

@end

這其實是個小詭計,也許相對于設(shè)置個動畫然后每次顯示一幀而言,用移動手勢來直接設(shè)置門的transform會更簡單。

在這個例子中的確是這樣,但是對于比如說關(guān)鍵這這樣更加復(fù)雜的情況,或者有多個圖層的動畫組,相對于實時計算每個圖層的屬性而言,這就顯得方便的多了。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號