先说下当前我为处理动画的思路: (新手上路, 老司机轻喷,如果有更好的实现方法请大神指教 感恩戴德)
#1. 分析动画构成
#2. 如果是位移动画则考虑使用BasicAnimation或者KeyframeAnimation实现, 需要的话再搭配缓动函数
#3. 比较复杂的动画则考虑是否用UIBezierpath一帧帧来画
今天我们模仿做一个场景切换加载等待动画, 比如这样的
我们分析下这张图的构成
#1. 一个灰色的背景
#2. 一个白色的圆环
#3. 一个闭合的圆弧(白色部分)
看起来不是简单的位移动画了, 我们用UIBezierPath加CADisplayLink一帧一帧来画试试看
灰色的背景,
这个比较简单, 我们直接创建一个UIView子类, 背景颜色设置为灰色
白色的圆环,
可以用UIBezierPath直接画一个圆,注意调整线的宽度 So easy
//添加外圆 UIBezierPath *apath = [UIBezierPath bezierPath]; apath.lineWidth = 5; [apath addArcWithCenter:CGPointMake(50, 50) radius:40 startAngle:0 endAngle:2 * M_PI clockwise:YES]; [apath stroke];
闭合的圆弧,
一样用UIBezierPath, 先设置圆心 画一个圆弧然后闭合路径, _count是设置的一个变量, 有Controller中的计时器控制以达到动画的效果
//先画内圆 //设置线条 path.lineWidth = 5; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; //设置圆心 [path moveToPoint:CGPointMake(_myWidth / 2, _myHeight / 2)]; //设置内切圆弧 [path addArcWithCenter:CGPointMake(_myWidth / 2, _myHeight / 2) radius:38 startAngle: M_PI * 3 / 2 endAngle:M_PI * 3 / 2 + 2 * M_PI / 300 * _count clockwise:YES]; //线路闭合 [path closePath]; [path fill];
要注意调整外圆和内闭合弧的线宽
然后在Controller中创建计时器, 改变_count的值达到动画的效果
上代码:
先创建一个UIView子类,
#import <UIKit/UIKit.h> @interface MyView : UIView @property (nonatomic, assign) CGFloat myWidth; @property (nonatomic, assign) CGFloat myHeight; @property (nonatomic, assign) NSInteger count; @end
在drawRect中添加图案
#import "MyView.h" @implementation MyView - (id)initWithFrame:(CGRect)frame { CGRect myFrame = CGRectMake(frame.origin.x, 0, frame.size.width, frame.size.height); self = [super initWithFrame:myFrame]; if (self) { self.myWidth = frame.size.width; self.myHeight = frame.size.height; } return self; } - (void)drawRect:(CGRect)rect { // Drawing code //设置线条颜色 UIColor *color = [UIColor whiteColor]; [color set]; //画内圆 UIBezierPath *path = [UIBezierPath bezierPath]; //设置线条 path.lineWidth = 5; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; //设置圆心 [path moveToPoint:CGPointMake(_myWidth / 2, _myHeight / 2)]; //设置内切圆弧 [path addArcWithCenter:CGPointMake(_myWidth / 2, _myHeight / 2) radius:38 startAngle: M_PI * 3 / 2 endAngle:M_PI * 3 / 2 + 2 * M_PI / 300 * _count clockwise:YES]; //线路闭合 [path closePath]; [path fill]; //添加外圆 UIBezierPath *apath = [UIBezierPath bezierPath]; apath.lineWidth = 5; [apath addArcWithCenter:CGPointMake(50, 50) radius:40 startAngle:0 endAngle:2 * M_PI clockwise:YES]; [apath stroke]; } @end
在Controller中调用
#import "ViewController.h" #import "MyView.h" @interface ViewController () @property (nonatomic, strong) MyView *myView; @property (nonatomic, strong) CADisplayLink *displayLink; @property (nonatomic, assign) NSInteger count; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //创建计时器 _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(countOn)]; _displayLink.paused = YES; [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; //创建自定义View实例 _myView = [[MyView alloc] initWithFrame:CGRectMake(150, 0, 100, 100)]; _myView.backgroundColor = [UIColor grayColor]; _myView.count = 1; [self.view addSubview:_myView]; //在这里可以添加额外动画, 设置hud出现的方式 [UIView animateWithDuration:0.5 animations:^{ _myView.frame = CGRectMake(150, 150, 100, 100); _displayLink.paused = NO; }]; } //计时器事件, 修改动画参数 - (void)countOn { _count++; _myView.count = _count; if (_count > 290) { [_displayLink invalidate]; [_myView removeFromSuperview]; } //重绘 [_myView setNeedsDisplay]; }
时间: 2024-10-24 03:26:03