1.扇形指示器
1.0、绘制扇形
首先画一个白色的扇形。创建一个MyLayer类继承自CALayer,重写它的绘图方法- (void)drawInContext:(CGContextRef)ctx
:
- (void)drawInContext:(CGContextRef)ctx { CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1); CGContextMoveToPoint(ctx, CGRectGetMaxX(self.bounds)/2, CGRectGetMaxY(self.bounds)); // 顺时针从-70度画到-110度 (0度是3点钟方向) CGContextAddArc(ctx, CGRectGetMaxX(self.bounds)/2, CGRectGetMaxY(self.bounds), 20, -70 * M_PI / 180, -110 * M_PI / 180, 1); CGContextClosePath(ctx); CGContextDrawPath(ctx, kCGPathFillStroke); }
1.1、之后创建一个MyActiveView类继承自UIView,把上面创建的layer添加到MyActiveView上。
@implementation MyActiveView { MyLayer *layer; CABasicAnimation *opacityAnim; } - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor clearColor]; CAReplicatorLayer *repLayer = [CAReplicatorLayer layer]; repLayer.frame = self.bounds; [self.layer addSublayer:repLayer]; // 画一个扇形的layer layer = [MyLayer layer]; layer.frame = CGRectMake(0, 0, 22, 22); // 调用layer的drawInContext:进行绘图 [layer setNeedsDisplay]; // 设置2倍比率,防止边缘出现锯齿 layer.contentsScale = 2; // 透明 layer.opacity = 0; // 设置锚点 layer.anchorPoint = CGPointMake(0.5, 0); // 设置第一个扇形layer的位置 layer.position = CGPointMake(self.bounds.size.width/2, 0); [repLayer addSublayer:layer]; // 设置透明度渐变的动画 opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"]; // 透明度从1变为0 opacityAnim.fromValue = [NSNumber numberWithFloat:1.0]; opacityAnim.toValue = [NSNumber numberWithFloat:0]; opacityAnim.removedOnCompletion = YES; opacityAnim.repeatCount = MAXFLOAT; CGFloat duration = 0.7; opacityAnim.duration = duration; [layer addAnimation:opacityAnim forKey:nil]; int count = 8; CGFloat angle = M_PI * 2 / count; // 复制8个 repLayer.instanceCount = count; // 绕z轴每隔angle角度复制一个 repLayer.instanceTransform = CATransform3DMakeRotation(angle, 0, 0, 1); // 复制子层动画延迟时长 repLayer.instanceDelay = duration / count; // 此视图绕z轴旋转22度 CATransform3D transform = CATransform3DRotate(self.layer.transform, 22*M_PI/180, 0, 0, 1); self.layer.transform = transform; // 监听App进入前后台 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:UIApplicationWillResignActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(start) name:UIApplicationDidBecomeActiveNotification object:nil]; } return self; } // 停止动画 - (void)stop { [layer removeAllAnimations]; } // 开始动画 - (void)start { [layer addAnimation:opacityAnim forKey:nil]; }
1.2使用示例:
MyActiveView *activityView = [[MyActiveView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width/2-25, self.view.bounds.size.height-200, 50, 50)]; [self.view addSubview:activityView];
2.圆形指示器
- (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // 设置直径为self宽/高的最小值 CGFloat diameter = MIN(frame.size.width, frame.size.height); CAShapeLayer *sLayer = [CAShapeLayer layer]; sLayer.anchorPoint = CGPointMake(0.5, 0.5); sLayer.frame = CGRectMake(0, 0, diameter, diameter); sLayer.strokeColor = [UIColor greenColor].CGColor; sLayer.fillColor = [UIColor clearColor].CGColor; sLayer.lineWidth = 2; CGFloat raduis = diameter/2; UIBezierPath *roundPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(raduis, raduis) radius:raduis startAngle:0 endAngle:(2*M_PI-M_PI_4) clockwise:YES]; sLayer.path = roundPath.CGPath; [self.layer addSublayer:sLayer]; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; animation.fromValue = @0; animation.toValue = @(2*M_PI); animation.duration = 1.f; animation.repeatCount = CGFLOAT_MAX; [sLayer addAnimation:animation forKey:nil]; } return self; }