Gráfico circular animado en iOS

Estoy tratando de crear un gráfico circular animado en iOS que actúa básicamente así:

Progresión del gráfico circular

En pocas palabras, comienza como un círculo gris y, a medida que avanza la animation, la flecha se mueve alnetworkingedor del círculo hasta llegar al porcentaje que especifique.

He usado el código de ejemplo que Zachary Waldowski publicó en esta pregunta SO:

Pie CAShapeLayer animado

Eso me llevó al punto donde puedo crear la animation básica. La pieza de pastel marrón crece para alcanzar el tamaño correcto. Lo que estoy luchando es cómo asignar la flecha a la animation para que se arrastre a medida que crece la pieza de pastel.

¿Alguna idea de cómo puedo lograr esto?

De acuerdo, encontré la solución.

Sobre la base del trabajo creado por Zachary Waldowski (ver mi publicación original), pude hacer todo en un CALayer .

En pocas palabras, dibujo un círculo externo en granate, un círculo más pequeño en gris claro, un path acariciado en blanco, y luego dibujo el triángulo con la punta de la flecha a mano.

Aquí está la sección relevante del código que hace la magia:

 - (void)drawInContext:(CGContextRef)context { CGRect circleRect = CGRectInset(self.bounds, 1, 1); CGFloat startAngle = -M_PI / 2; CGFloat endAngle = self.progress * 2 * M_PI + startAngle; CGColorRef outerPieColor = [[UIColor colorWithRed: 137.0 / 255.0 green: 12.0 / 255.0 blue: 88.0 / 255.0 alpha: 1.0] CGColor]; CGColorRef innerPieColor = [[UIColor colorWithRed: 235.0 / 255.0 green: 214.0 / 255.0 blue: 227.0 / 255.0 alpha: 1.0] CGColor]; CGColorRef arrowColor = [[UIColor whiteColor] CGColor]; // Draw outer pie CGFloat outerRadius = CGRectGetMidX(circleRect); CGPoint center = CGPointMake(CGRectGetMidX(circleRect), CGRectGetMidY(circleRect)); CGContextSetFillColorWithColor(context, outerPieColor); CGContextMoveToPoint(context, center.x, center.y); CGContextAddArc(context, center.x, center.y, outerRadius, startAngle, endAngle, 0); CGContextClosePath(context); CGContextFillPath(context); // Draw inner pie CGFloat innerRadius = CGRectGetMidX(circleRect) * 0.45; CGContextSetFillColorWithColor(context, innerPieColor); CGContextMoveToPoint(context, center.x, center.y); CGContextAddArc(context, center.x, center.y, innerRadius, startAngle, endAngle, 0); CGContextClosePath(context); CGContextFillPath(context); // Draw the White Line CGFloat lineRadius = CGRectGetMidX(circleRect) * 0.72; CGFloat arrowWidth = 0.35; CGContextSetStrokeColorWithColor(context, arrowColor); CGContextSetFillColorWithColor(context, arrowColor); CGMutablePathRef path = CGPathCreateMutable(); CGContextSetLineWidth(context, 16); CGFloat lineEndAngle = ((endAngle - startAngle) >= arrowWidth) ? endAngle - arrowWidth : endAngle; CGPathAddArc(path, NULL, center.x, center.y, lineRadius, startAngle, lineEndAngle, 0); CGContextAddPath(context, path); CGContextStrokePath(context); // Draw the Triangle pointer CGFloat arrowStartAngle = lineEndAngle - 0.01; CGFloat arrowOuterRadius = CGRectGetMidX(circleRect) * 0.90; CGFloat arrowInnerRadius = CGRectGetMidX(circleRect) * 0.54; CGFloat arrowX = center.x + (arrowOuterRadius * cosf(arrowStartAngle)); CGFloat arrowY = center.y + (arrowOuterRadius * sinf(arrowStartAngle)); CGContextMoveToPoint (context, arrowX, arrowY); // top corner arrowX = center.x + (arrowInnerRadius * cosf(arrowStartAngle)); arrowY = center.y + (arrowInnerRadius * sinf(arrowStartAngle)); CGContextAddLineToPoint(context, arrowX, arrowY); // bottom corner arrowX = center.x + (lineRadius * cosf(endAngle)); arrowY = center.y + (lineRadius * sinf(endAngle)); CGContextAddLineToPoint(context, arrowX, arrowY); // point CGContextClosePath(context); CGContextFillPath(context); [super drawInContext: context]; } 

Tienen el pastel con la flecha como image.

En cada paso, dibuja esta image, girándola un poco. Dibuja el pastel gris sobre la image, eligiendo los angularjs correctos para la rotation de la image.