layout: post
title: "Nice 標簽動畫分析"
date: 2015-04-05 16:51:25 +0800
comments: true
categories: iOS 動畫
上圖是模仿nice中的標簽,接下來分析構建這個控件的過程煤辨。
開始需要看下iOS的顯示動畫 以及 CAAnimationGroup
1. 中間icon的放大縮小動畫
首先給layer設置image icon永部,
layer.contents = (__bridge id)(icon.CGImage);
通過 “transform.scale”這個keypath 來收縮layer,縮放過程如下:
1 縮小到0.8倍
2 放大到1.2倍
3 復原到1.0倍
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = @1;
animation.toValue = @0.8;
animation.duration = 0.2;
CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation1.fromValue = @0.8;
animation1.toValue = @1.2;
animation1.duration = 0.4;
animation1.beginTime = animation.duration;
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation2.fromValue = @1.2;
animation2.toValue = @1;
animation2.duration = 0.2;
animation2.beginTime = animation.duration + animation1.duration;
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.duration = animation.duration + animation1.duration + animation2.duration + 0.1;
animationGroup.repeatCount = 0;
animationGroup.delegate = self;
animationGroup.animations = @[animation,animation1,animation2];
[animationGroup setValue:@"icon" forKey:@"animationName"];
```
CAAnimationGroup中的動畫都是并發(fā)執(zhí)行的毙替,所以icon動畫關鍵是通過beginTime設置每個動畫開始播放的時間墨榄,repeatCount=0,所有動畫都為單次播放。
## 2. 脈沖動畫
```objc
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation3.fromValue = @0.0;
animation3.toValue = @1.0;
animation3.duration = duration;
//關鍵幀動畫
CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
animation4.duration =duration ;
animation4.values = @[@0.8, @0.45, @0];
animation4.keyTimes = @[@0, @0.2, @1];
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
.......
[animationGroup setValue:@"pulse" forKey:@"animationName"];
```
通過CAAnimationGroup來實現(xiàn)layer一邊放大,一邊設置透明度來實現(xiàn)脈沖效果只怎,
## 3. 通過Animation的delegate來組合動畫
看圖是整個動畫是由 一個收縮動畫 兩個脈沖動畫組合起來的,組合過程就是由各個CAAnimationGroup的delegate來合成的
```objc
- (void)animationDidStart:(CAAnimation *)animation{ //等第一個脈沖動畫播放到0.5秒怜俐,開始播放第二個動畫
NSString *animationName = [animation valueForKey:@"animationName"];
if ([animationName isEqualToString:@"pulse"]) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * self.pulsingGroup.duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[pulsingLayer1 addAnimation:pulsingGroup1 forKey:@"pulse1"];
});
}
}
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished{
NSString *animationName = [animation valueForKey:@"animationName"];
if ([animationName isEqualToString:@"icon"]) { //icon動畫播放完結束后添加脈沖動畫
[imageLayer removeAnimationForKey:@"icon"];
[pulsingLayer addAnimation:pulsingGroup forKey:@"pulse"];
}else if ([animationName isEqualToString:@"pulse"]){ //第一個脈沖動畫播放完成后移除
[pulsingLayer removeAnimationForKey:@"pulse"];
}else if ([animationName isEqualToString:@"pulse1"]){//第二個脈沖動畫播放后身堡,再開始循環(huán)播放icon動畫
[pulsingLayer1 removeAnimationForKey:@"pulse1"];
[imageLayer addAnimation:iconGroup forKey:@"icon"];
}
}
4. 繪制箭頭
首先計算tag上文字的寬度加上 除去文字的其他寬度,算出tag的寬度佑菩, 然后找到這個箭頭的5個角盾沫, 通過addArcWithCenter 這個方法 (在每個角上畫上一個圓,確定每個圓的半徑殿漠、圓心以及角度赴精。) 分別在5個角上畫5段弧線。然后 使用 [path fill]來填充背景顏色绞幌。
5. 繪制文字
NSDictionary *attributes = @{
NSShadowAttributeName : shadow,
NSForegroundColorAttributeName : [UIColor colorWithRed:255 green:255 blue:255 alpha:1],
NSFontAttributeName : [UIFont systemFontOfSize:14]
};
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text attributes:attributes];
[attributedText drawInRect:CGRectMake(0,0,100,height)]
總結
整個控件的動畫都是由CAAnimationGroup的delegate調度的蕾哟,每個CAAnimationGroup完成后,繼續(xù)另外一個動畫莲蜘。 繪制箭頭的時候比較麻煩的是確定每個圓角的角度谭确、半徑與圓點,最好在Photoshop或者Sketch上確定好票渠。
在使用過程中逐哈,有可能需要需要縮小,這個時候可以通過view的矩陣變換 transform CGAffineTransformMakeScale 來設置大小问顷。