iOS實現點贊動畫特效

本文實例為大傢分享瞭iOS實現點贊動畫特效的具體代碼,供大傢參考,具體內容如下

動畫的基本使用

動畫的實現基本上是基於對View控件和View的layer屬性進行操作,對視圖進行移動,尺寸變換,透明度變換,旋轉等一系列操作。

關鍵幀動畫:

動畫的實現可以分為兩個部分,一部分是規定動畫的變化內容,比如view需要把scale從0變化到1,這個數字是相對值,即從尺寸為0變化到正常尺寸。另一個部分是規定動畫的漸變時間。這樣就實現瞭view在規定時間完成指定變化瞭,這個變化的過程也可以通過參數設置為非均勻變化的。上面的示例是關鍵幀動畫的實現,實現的方式是把動畫劃分為幾個部分,“第一幀”做一件事,“第二幀”再做另外一件事,這就使得變化連續且可控。Duration參數確定瞭時間,delay確定瞭延時多久執行,options確定瞭關鍵幀動畫佈局子控件。completion的參數是一個block,其中的內容是在內容執行結束後才調用。這裡做瞭3幀,前兩幀做瞭尺寸變為3倍然後恢復,後一幀使得其隱藏。結束後會調用block使其移除。

[UIView animateKeyframesWithDuration:self.animationDurtion * 4 delay:0.0 options:UIViewKeyframeAnimationOptionLayoutSubviews animations:^{
   /*參數1:關鍵幀開始時間
    參數2:關鍵幀占用時間比例
    參數3:到達該關鍵幀時的屬性值 */
   [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 * self.animationDurtion animations:^{
    giveLikeView.transform = CGAffineTransformMakeScale(3, 3);;
   }];
   [UIView addKeyframeWithRelativeStartTime:0.5 * self.animationDurtion relativeDuration:0.5 * self.animationDurtion animations:^{
    giveLikeView.transform = CGAffineTransformIdentity;
   }];
   [UIView addKeyframeWithRelativeStartTime:self.animationDurtion relativeDuration:self.animationDurtion * 3 animations:^{
    giveLikeView.alpha = 0;
   }];
  } completion:^(BOOL finished) {
   giveLikeView.hidden = YES;
   [giveLikeView removeFromSuperview];
  }];

CAShapeLayer和UIBezierPath:

當不滿足於view的變化,還需要在view的表面繪制一些圖案,就要對layer進行操作,layer可以理解為是view的表面,每個view都有layer參數。UIBezierPath是貝塞爾曲線,它用於設置繪圖的路徑,沒有瞭它,layer的繪制也是無效的,因為沒有邊界呀。
如下代碼繪制瞭一個圓形的曲線,設置瞭它的中心,半徑,起始終止角這些屬性。

UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(giveLikeView.bounds.size.width/2, giveLikeView.bounds.size.height/2) radius:giveLikeView.bounds.size.width startAngle:-1.57 endAngle:-1.57+3.14*2 clockwise:YES];
 circleLayer.path = bezierPath.CGPath;
 [self.layer addSublayer:circleLayer];

在最後我們可以看到:circleLayer.path = bezierPath.CGPath; [self.layer addSublayer:circleLayer];
它的作用是設置layer的路徑,並把layer添加到view的表面。下面來看看layer的配置。
創建一個layer後設置它的frame和顏色以及邊界,線寬這些屬性。

CAShapeLayer *circleLayer = [[CAShapeLayer alloc] init];
circleLayer.frame = giveLikeView.frame;
circleLayer.fillColor = [UIColor clearColor].CGColor;
circleLayer.strokeColor = [UIColor redColor].CGColor;
circleLayer.lineWidth = 1;

幾處聯系:把貝塞爾曲線和layer聯系起來,把layer和view的layer聯系起來。

為layer加動畫(動畫組):

先創建動畫組CAAnimationGroup,它可以容納若幹動畫,然後創建若幹CABasicAnimation基礎動畫。分別設置屬性,動畫組需要涉及的屬性有時間功能,kCAMediaTimingFunctionEaseIn表示逐漸加快,另外還有設置持續時間,設置kCAFillModeForwards表示動畫在結束後會保持,removedOnCompletion = NO表示最後不移除。在基礎動畫的設置中,一般設置在動畫組中的起始時間和持續時間,還有參數的變化。最後的 group.animations = @[scaleAnimtion,widthStartAnimtion,widthEndAnimtion];[circleLayer addAnimation:group forKey:nil];
兩句表示在動畫組中添加動畫然後為layer添加動畫組,這樣layer就有動畫特效瞭。

//動畫
CAAnimationGroup *group = [CAAnimationGroup animation];
 group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
 NSTimeInterval groupInterval = self.animationDurtion * 0.8;
 group.duration = groupInterval;
 group.fillMode = kCAFillModeForwards;
 group.removedOnCompletion = NO;
 
CABasicAnimation * scaleAnimtion = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
 scaleAnimtion.beginTime = 0;
 scaleAnimtion.duration = groupInterval * 0.8;
 scaleAnimtion.fromValue = @(0);
 scaleAnimtion.toValue = @(1);
 
CABasicAnimation * widthStartAnimtion = [CABasicAnimation animationWithKeyPath:@"lineWidth"];
 widthStartAnimtion.beginTime = 0;
 widthStartAnimtion.duration = groupInterval * 0.8;
 widthStartAnimtion.fromValue = @(1);
 widthStartAnimtion.toValue = @(2);
 
CABasicAnimation * widthEndAnimtion = [CABasicAnimation animationWithKeyPath:@"lineWidth"];
 widthEndAnimtion.beginTime = groupInterval * 0.8;
 widthEndAnimtion.duration = groupInterval * 0.2;
 widthEndAnimtion.fromValue = @(2);
 widthEndAnimtion.toValue = @(0);
 
 group.animations = @[scaleAnimtion,widthStartAnimtion,widthEndAnimtion];
 [circleLayer addAnimation:group forKey:nil];

點贊動畫的實現原理

下面來介紹demo的實現原理。

controller的尺寸設置為全屏,在其上方也覆蓋一個全屏的view,再在view上添加點擊事件(手勢)。

- (void)addGesture
{
 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(creatOneHeart:)];
 [self addGestureRecognizer:tap]; 
}

下面看看點擊後調用的方法:

這裡每次點擊都會獲取點擊的位置然後去初始化一個愛心,這是異步任務,放在主隊列中執行。

- (void)creatOneHeart:(UITapGestureRecognizer *)sender
{
 CGPoint point = [sender locationInView:self];
 dispatch_async(dispatch_get_main_queue(),^{
  [self initOneNewHeart:point];
 });
}

這段代碼創建瞭視圖對象,這裡自然用到瞭事先創建好的心形圖片。這裡把創建的imageview存到隊列,顯示到view上,最後調用likeAction:方法執行動畫。

- (UIImageView *)createGiveLikeView
{
 UIImageView *giveLikeView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
 giveLikeView.backgroundColor = [UIColor clearColor];
 UIImage *image = [UIImage imageNamed:@"icon_home_like_after"];
 giveLikeView.userInteractionEnabled = YES;
 giveLikeView.tag = GiveType;
 giveLikeView.image = image;
 giveLikeView.hidden = NO;
 _giveLikeView = giveLikeView;
 return _giveLikeView;
}
- (void)initOneNewHeart:(CGPoint)point
{
 UIImageView *giveLikeView = [self createGiveLikeView];
 giveLikeView.center = point;
 [self.array addObject:giveLikeView];
 [self addSubview:giveLikeView];
 [self likeAction:giveLikeView];
}

我們看看giveLikeAction:這個方法,它包括執行心形的變化動畫和繪制六個輻射的三角形動畫,還有輻散的圓的動畫。

- (void)likeAction:(UIImageView *)giveLikeView
{
 [self giveLikeAction:giveLikeView];
}
- (void)giveLikeAction:(UIImageView *)giveLikeView
{
 [self animtionChangeLikeType:giveLikeView];
 [self createTrigonsAnimtion:giveLikeView];
 [self createCircleAnimation:giveLikeView];
}

接下來直接看看輻散的三角形的動畫(愛心的變化動畫在上面已經涉及到瞭):
這段代碼跑瞭6個循環,做瞭6個三角形,它們分別有動畫效果。
shape.transform = CATransform3DMakeRotation(3.14 / 3 * i, 0, 0, 1);實現瞭旋轉。
[giveLikeView.layer addSublayer:shape];執行layer的添加。
因為在循環中,每個layer都有獨立的動畫,動畫組實現的效果是三角形從小變大,最後變成一條直線並消失。
下面的兩行代碼用到瞭__bridge,它的作用是實現類型的轉換,這裡把CGPathRef類型“橋接”轉化為瞭id類型,如果沒有它,會報錯。
pathAnimation.fromValue = (__bridge id)startPath.CGPath;
pathAnimation.toValue = (__bridge id)endPath.CGPath;

- (void)createTrigonsAnimtion:(UIImageView *)giveLikeView
{
 for(int i=0;i<6;i++) {
  //創建一個layer並設置位置和填充色
  CAShapeLayer *shape = [[CAShapeLayer alloc] init];
  shape.position = CGPointMake(giveLikeView.bounds.size.width/2, giveLikeView.bounds.size.height/2);
  shape.fillColor = [UIColor redColor].CGColor;
  //設置貝塞爾曲線,執行路徑
  UIBezierPath *startPath = [[UIBezierPath alloc] init];
  [startPath moveToPoint:CGPointMake(-2, 30)];
  [startPath addLineToPoint:CGPointMake(2, 30)];
  [startPath addLineToPoint:CGPointMake(0, 0)];
  [startPath addLineToPoint:CGPointMake(-2, 30)];
  shape.path = startPath.CGPath;
  
  //旋轉
  shape.transform = CATransform3DMakeRotation(3.14 / 3 * i, 0, 0, 1);
  [giveLikeView.layer addSublayer:shape];
  
  //動畫組
  CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
  groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  groupAnimation.duration = self.animationDurtion;
  groupAnimation.fillMode = kCAFillModeForwards;
  groupAnimation.removedOnCompletion = NO;
  
  //基礎動畫1
  CABasicAnimation *scaleAnimtion = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
  //縮放時間占20%
  scaleAnimtion.duration = self.animationDurtion * 0.2;
  scaleAnimtion.fromValue = @(0);
  scaleAnimtion.toValue = @(1);

  //繪制三角形結束 一條直線
  UIBezierPath *endPath = [UIBezierPath bezierPath];
  [endPath moveToPoint:CGPointMake(-2, 30)];
  [endPath addLineToPoint:CGPointMake(2, 30)];
  [endPath addLineToPoint:CGPointMake(0, 30)];

  //基礎動畫2
  CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
  pathAnimation.beginTime = self.animationDurtion * 0.2;
  pathAnimation.duration = self.animationDurtion * 0.8;
  pathAnimation.fromValue = (__bridge id)startPath.CGPath;
  pathAnimation.toValue = (__bridge id)endPath.CGPath;

  groupAnimation.animations = @[scaleAnimtion,pathAnimation];
  [shape addAnimation:groupAnimation forKey:nil];
 }
}

demo實現的動畫效果

demo的GitHub鏈接

最後附上demo鏈接:MYFGiveLikeAnimationDemo

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: