在iOS开发的时候,我们可以借助UIBezierPath和CAShapeLayer这两个类来实现画圆的需求,另外我们还可以给圆设置颜色、宽度,设置画圆的动画可以借助CABasicAnimation来实现。下面是代码实现部分。
CGRect rect = CGRectMake(100, 100, 100, 100);
UIBezierPath *beizPath=[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:50];
//先画一个圆
CAShapeLayer *layer=[CAShapeLayer layer];
layer.path=beizPath.CGPath;
layer.fillColor=[UIColor clearColor].CGColor;//填充色
layer.strokeColor=[UIColor redColor].CGColor;//边框颜色
layer.lineWidth=6.0f;
layer.lineCap=kCALineCapRound;//线框类型
[self.view.layer addSublayer:layer];
CABasicAnimation *animation=[CABasicAnimation animationWithKeyPath:@"strokeEnd"];
animation.fromValue=[NSNumber numberWithFloat:0.0f];
animation.toValue=[NSNumber numberWithFloat:toValue];
animation.duration=2.0;
//animation.repeatCount=HUGE;//永久重复动画
//animation.delegate=self;
//removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
//fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
//autoreverses:动画结束时是否执行逆动画
//timingFunction:设定动画的速度变化
//kCAFillModeBackwards 可以让动画闭合
//kCAFillModeForwards 动画不会闭合
animation.fillMode=kCAFillModeForwards;
animation.removedOnCompletion=NO;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[layer addAnimation:animation forKey:@"animation"];
另外我们可能还会有一部分的特殊动画效果需要我们来实现,就像雷达波纹效果、不规则图形划线这样的设置,这里也是有办法来实现的。
实例如下:
_testView=[[UIView alloc] initWithFrame:CGRectMake(30, 300, 100, 100)];
[self.view addSubview:_testView];
_testView.layer.backgroundColor = [UIColor clearColor].CGColor;
//CAShapeLayer和CAReplicatorLayer都是CALayer的子类
//CAShapeLayer的实现必须有一个path,可以配合贝塞尔曲线
CAShapeLayer *pulseLayer = [CAShapeLayer layer];
pulseLayer.frame = _testView.layer.bounds;
pulseLayer.path = [UIBezierPath bezierPathWithOvalInRect:pulseLayer.bounds].CGPath;
pulseLayer.fillColor = [UIColor redColor].CGColor;//填充色
pulseLayer.opacity = 0.0;
//可以复制layer
CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
replicatorLayer.frame = _testView.bounds;
replicatorLayer.instanceCount = 4;//创建副本的数量,包括源对象。
replicatorLayer.instanceDelay = 1;//复制副本之间的延迟
[replicatorLayer addSublayer:pulseLayer];
[_testView.layer addSublayer:replicatorLayer];
CABasicAnimation *opacityAnima = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnima.fromValue = @(0.3);
opacityAnima.toValue = @(0.0);
CABasicAnimation *scaleAnima = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnima.fromValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 0.0, 0.0, 0.0)];
scaleAnima.toValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 1.0, 1.0, 0.0)];
CAAnimationGroup *groupAnima = [CAAnimationGroup animation];
groupAnima.animations = @[opacityAnima, scaleAnima];
groupAnima.duration = 4.0;
groupAnima.autoreverses = NO;
groupAnima.repeatCount = HUGE;
[pulseLayer addAnimation:groupAnima forKey:@"groupAnimation"];
这里的_testview就是测试view通过对这个view的操作设置来实现雷达波纹扩散的效果。
不规则图形的划线的实例如下:
UIView *line=[[UIView alloc] initWithFrame:CGRectMake(0, 100, 400, 1)];
line.backgroundColor=[UIColor grayColor];
[self.view addSubview:line];
_testView1=[[UIImageView alloc] initWithFrame:CGRectMake(0, 100, 300, 200)];
_testView1.userInteractionEnabled=YES;
[self.view addSubview:_testView1];
//贝塞尔曲线,以下是4个角的位置,相对于_testView1
CGPoint point1= CGPointMake(10, 80);
CGPoint point2= CGPointMake(10, 200);
CGPoint point3= CGPointMake(300, 200);
CGPoint point4= CGPointMake(300, 80);
_path=[UIBezierPath bezierPath];
[_path moveToPoint:point1];//移动到某个点,也就是起始点
[_path addLineToPoint:point2];
[_path addLineToPoint:point3];
[_path addLineToPoint:point4];
//controlPoint控制点,不等于曲线顶点
[_path addQuadCurveToPoint:point1 controlPoint:CGPointMake(150, -30)];
CAShapeLayer *shapeLayer=[CAShapeLayer layer];
shapeLayer.path=_path.CGPath;
shapeLayer.fillColor=[UIColor clearColor].CGColor;//填充颜色
shapeLayer.strokeColor=[UIColor orangeColor].CGColor;//边框颜色
[_testView1.layer addSublayer:shapeLayer];
//动画
CABasicAnimation *pathAniamtion = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAniamtion.duration = 3;
pathAniamtion.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAniamtion.fromValue = [NSNumber numberWithFloat:0.0f];
pathAniamtion.toValue = [NSNumber numberWithFloat:1.0];
pathAniamtion.autoreverses = NO;
[shapeLayer addAnimation:pathAniamtion forKey:nil];
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickk:)];
[_testView1 addGestureRecognizer:tap];