手動動畫(9.2 圖層時間)
阿新 • • 發佈:2017-10-05
void ner pda horizon aps splay container load set
手動動畫
timeOffset
一個很有用的功能在於你可以它可以讓你手動控制動畫進程,通過設置speed
為0,可以禁用動畫的自動播放,然後來使用timeOffset
來來回顯示動畫序列。這可以使得運用手勢來手動控制動畫變得很簡單。
舉個簡單的例子:還是之前關門的動畫,修改代碼來用手勢控制動畫。我們給視圖添加一個UIPanGestureRecognizer
,然後用timeOffset
左右搖晃。
因為在動畫添加到圖層之後不能再做修改了,我們來通過調整layer
的timeOffset
達到同樣的效果(清單9.4)。
清單9.4 通過觸摸手勢手動控制動畫
1 @interface ViewController ()View Code2 3 @property (nonatomic, weak) UIView *containerView; 4 @property (nonatomic, strong) CALayer *doorLayer; 5 6 @end 7 8 @implementation ViewController 9 10 - (void)viewDidLoad 11 { 12 [super viewDidLoad]; 13 //add the door 14 self.doorLayer = [CALayer layer]; 15 self.doorLayer.frame = CGRectMake(0, 0, 128, 256); 16 self.doorLayer.position = CGPointMake(150 - 64, 150); 17 self.doorLayer.anchorPoint = CGPointMake(0, 0.5); 18 self.doorLayer.contents = (__bridge id)[UIImage imageNamed:@"Door.png"].CGImage; 19 [self.containerView.layer addSublayer:self.doorLayer]; 20 //apply perspective transform21 CATransform3D perspective = CATransform3DIdentity; 22 perspective.m34 = -1.0 / 500.0; 23 self.containerView.layer.sublayerTransform = perspective; 24 //add pan gesture recognizer to handle swipes 25 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] init]; 26 [pan addTarget:self action:@selector(pan:)]; 27 [self.view addGestureRecognizer:pan]; 28 //pause all layer animations 29 self.doorLayer.speed = 0.0; 30 //apply swinging animation (which won‘t play because layer is paused) 31 CABasicAnimation *animation = [CABasicAnimation animation]; 32 animation.keyPath = @"transform.rotation.y"; 33 animation.toValue = @(-M_PI_2); 34 animation.duration = 1.0; 35 [self.doorLayer addAnimation:animation forKey:nil]; 36 } 37 38 - (void)pan:(UIPanGestureRecognizer *)pan 39 { 40 //get horizontal component of pan gesture 41 CGFloat x = [pan translationInView:self.view].x; 42 //convert from points to animation duration //using a reasonable scale factor 43 x /= 200.0f; 44 //update timeOffset and clamp result 45 CFTimeInterval timeOffset = self.doorLayer.timeOffset; 46 timeOffset = MIN(0.999, MAX(0.0, timeOffset - x)); 47 self.doorLayer.timeOffset = timeOffset; 48 //reset pan gesture 49 [pan setTranslation:CGPointZero inView:self.view]; 50 } 51 52 @end
這其實是個小詭計,也許相對於設置個動畫然後每次顯示一幀而言,用移動手勢來直接設置門的transform
會更簡單。
在這個例子中的確是這樣,但是對於比如說關鍵這這樣更加復雜的情況,或者有多個圖層的動畫組,相對於實時計算每個圖層的屬性而言,這就顯得方便的多了。
手動動畫(9.2 圖層時間)