iOS核心動畫實現仿支付寶咻咻、雷達效果


今天閑余時間寫了一個類似支付寶咻咻或者說雷達效果。望大神勿笑、寫的粗糙。


更新了下文章,貼出Demo地址
github


先上效果圖吧:


雷達效果圖
說下主要思路吧:

主要用到了CAShapeLayer和UIBezierPath的經典結合畫出自己想要的圖再結合CAAnimation將動畫添加到layer上實現效果。


timingFunction:動畫的運動軌跡,用於變化起點和終點之間的插值計算,即它決定了動畫運行的節奏,比如是均 勻變化(相同時間變化量相同)還是先快后慢,先慢后快還是先慢再快再慢。
動畫的開始與結束的快慢,有五個預置分別為:
kCAMediaTimingFunctionLinear
線性,即勻速
kCAMediaTimingFunctionEaseIn 先慢后快
kCAMediaTimingFunctionEaseOut 先快后慢
kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
kCAMediaTimingFunctionDefault 中間快

代碼部分 ( 基本全部代碼)
自定義一個view-- RadarAnimationView.h:

這里提供了一些屬性、可以在外部進行設置。

 //定義Block的目的是為了點擊雷達中間按鈕時調用,此處定義,方便以后使用。 typedef void(^RaderBtnBlock)(); typedef void(^RaderBtnSelectBlock)(); #import <UIKit/UIKit.h> //雷達效果 @interface RadarAnimationView : UIView /** * 按鈕圖片 */ @property (nonatomic ,strong) UIImage *image; /** * 按鈕選中圖片 */ @property (nonatomic ,strong) UIImage *selectImage; /** * 波紋顏色 */ @property (nonatomic,strong) UIColor *raderColor; /** * 按鈕block 未選擇狀態 */ @property (nonatomic,copy) RaderBtnBlock block; /** * 按鈕block 選擇狀態 */ @property (nonatomic,copy) RaderBtnSelectBlock selectBlock; @end
RadarAnimationView.m實現部分
static const float timeinterval = 0.5; #import <QuartzCore/QuartzCore.h> #import "RadarAnimationView.h" @interface RadarAnimationView () { //定時器 NSTimer *_timer; } //按鈕圖片 @property (nonatomic,strong)UIButton *iamgeBtn; @end @implementation RadarAnimationView - (void)drawRect:(CGRect)rect { self.alpha = 0.5; //創建定時器 _timer = [NSTimer scheduledTimerWithTimeInterval:timeinterval target:self selector:@selector(setUp) userInfo:nil repeats:YES]; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _iamgeBtn = [[UIButton alloc] initWithFrame:self.bounds]; [_iamgeBtn addTarget:self action:@selector(imageBtnClick:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_iamgeBtn]; //設置默認波紋顏色 self.raderColor = [UIColor blueColor]; } return self; } //按鈕點擊事件 -(void)imageBtnClick:(UIButton *)btn { if (btn.selected) { NSLog(@"1"); //調用block self.block(@"1"); }else { NSLog(@"2"); //調用block self.selectBlock(@"2"); } btn.selected = !btn.selected; } //重寫setter方法 -(void)setImage:(UIImage *)image { _image = image; [self.iamgeBtn setImage:image forState:0]; } -(void)setSelectImage:(UIImage *)selectImage { _selectImage = selectImage; [self.iamgeBtn setImage:selectImage forState:1]; } -(void)setRaderColor:(UIColor *)raderColor { _raderColor = raderColor; } //畫雷達圓圈圖 -(void)setUp { CGPoint center = CGPointMake(self.bounds.size.height / 2, self.bounds.size.width / 2); //使用貝塞爾畫圓 UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:50 startAngle:0 endAngle:2 * M_PI clockwise:YES]; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.frame = self.bounds; //填充顏色 shapeLayer.fillColor = self.raderColor.CGColor; //設置透明度、此處最好和動畫里的一致、否則效果會不好 shapeLayer.opacity = 0.2; shapeLayer.path = path.CGPath; [self.layer insertSublayer:shapeLayer below:self.iamgeBtn.layer]; [self addAnimation:shapeLayer]; } -(void)addAnimation:(CAShapeLayer *)shapeLayer { //雷達圈圈大小的動畫 CABasicAnimation *basicAnimation = [CABasicAnimation animation]; basicAnimation.keyPath = @"path"; CGPoint center = CGPointMake (self.bounds.size.height / 2, self.bounds.size.width / 2); UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:center radius:1 startAngle:0 endAngle:2 * M_PI clockwise:YES]; UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:center radius:[UIScreen mainScreen].bounds.size.height startAngle:0 endAngle:2 * M_PI clockwise:YES]; basicAnimation.fromValue = (__bridge id _Nullable)(path1.CGPath); basicAnimation.toValue = (__bridge id _Nullable)(path2.CGPath); //保持最新狀態 basicAnimation.fillMode = kCAFillModeForwards; //雷達圈圈的透明度 CABasicAnimation *opacityAnimation = [CABasicAnimation animation]; opacityAnimation.keyPath = @"opacity"; opacityAnimation.fromValue = @(0.2); opacityAnimation.toValue = @(0); opacityAnimation.fillMode = kCAFillModeForwards; //組動畫 CAAnimationGroup *group = [CAAnimationGroup animation]; group.animations = @[basicAnimation,opacityAnimation]; group.duration = 7; //動畫定時函數屬性 先快后慢 group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; group.delegate = self; //指定的時間段完成后,動畫就自動的從層上移除 group.removedOnCompletion = YES; //添加動畫到layer [shapeLayer addAnimation:group forKey:nil]; } #pragma mark 動畫結束 -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { //雖然效果實現了、而且在內存上也基本在25m旁邊.但是實現雷達波紋的波浪是一直在創建對象、所以下敘是為了及時釋放不用的Shapelayear。 //此種方法欠妥、后面有時間會做更新 if (flag) { NSLog(@"----"); //釋放動畫結束的對象 獲取最上層layer if ([self.layer.sublayers[0] isKindOfClass:[CAShapeLayer class]]) { CAShapeLayer *shaperLayer = (CAShapeLayer *)self.layer.sublayers[0]; [shaperLayer removeFromSuperlayer]; shaperLayer = nil; NSLog(@"%lu",self.layer.sublayers.count); } } } @end
在VC中調用
// #import "ViewController.h" #import "RadarAnimationView.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:23/255.0 green:26/255.0 blue:40/255.0 alpha:1]; RadarAnimationView *rader = [[RadarAnimationView alloc]initWithFrame:CGRectMake(100, 100, 50, 50)]; rader.center = self.view.center; rader.backgroundColor = [UIColor lightGrayColor]; rader.image = [UIImage imageNamed:@"IMG_1314.JPG"]; //點擊按鈕時兩種狀態調用的兩種block rader.block = ^{ NSLog(@"1"); }; rader.selectBlock = ^{ NSLog(@"2"); }; [self.view addSubview:rader]; } @end

好了基本實現了。

 


文/MoreCookies(簡書作者)
原文鏈接:http://www.jianshu.com/p/c99bea074aad
著作權歸作者所有,轉載請聯系作者獲得授權,並標注“簡書作者”。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM