1. Introduction to CAShape Layer
- CAShapeLayer is a subclass of layers drawn by vector graphics rather than bitmap.
- CAShapeLayer inherits from CALayer and can use all attribute values of CALayer.
- CAShapeLayer needs to be used in conjunction with the Bessel curve to make sense (this is personal experience).
- Using CAShapeLayer and Bessel curves, you can draw the figure you want.
- Compared with Core Graphics, using CAShape Layer has the following advantages:
- Fast rendering. CAShapeLayer uses hardware acceleration (CPU rendering) to draw the same graph much faster than Core Graphics.
- Use memory efficiently. A CAShapeLayer doesn't need to create a boarding graph like a normal CALayer, so no matter how big it is, it won't take up too much memory.
- It won't be clipped off by layer boundaries. A CAShapeLayer can be drawn outside the boundary.
2. Brief introduction of Bessel curve
stay Mathematics Of numerical analysis In the field, the B e zier curve is computer graphics Of considerable importance Parametric curve. (Bessel Curve Literacy)
Bessel curve corresponds to UIBezierPath object in iOS, which is the encapsulation of CGPathRef data type. If path is based on vector shape, it is created with straight lines and curve segments. We use line segments to create rectangles and polygons, and curve segments to create arc s, circles or other complex curve shapes.
3. Simple Use
Draw a straight line and an ellipse using CAShapeLayer and UIBezierPath. The effect is as follows:
The code is as follows:
// 1. Draw a straight line UIBezierPath * path = [[UIBezierPath alloc] init]; path.lineWidth = 1.f; //Set the starting point [path moveToPoint:CGPointMake(0, 10)]; //Add subpaths [path addLineToPoint:CGPointMake(300, 10)]; CAShapeLayer * shapeLayer = [CAShapeLayer layer]; shapeLayer.backgroundColor = [UIColor yellowColor].CGColor; shapeLayer.frame = CGRectMake(0, 0, 300, 50); shapeLayer.position = self.view.center; shapeLayer.fillColor = [UIColor clearColor].CGColor; shapeLayer.strokeColor = [UIColor redColor].CGColor; shapeLayer.path = path.CGPath; [self.view.layer addSublayer:shapeLayer]; // 2. Draw an ellipse UIBezierPath * path2 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 10, 100, 50)]; CAShapeLayer * shapeLayer2 = [CAShapeLayer layer]; shapeLayer2.backgroundColor = [UIColor blueColor].CGColor; shapeLayer2.frame = CGRectMake(0, 0, 300, 150); shapeLayer2.position = CGPointMake(self.view.center.x, self.view.center.y+70); shapeLayer2.fillColor = [UIColor clearColor].CGColor; shapeLayer2.strokeColor = [UIColor redColor].CGColor; shapeLayer2.path = path2.CGPath; [self.view.layer addSublayer:shapeLayer2];
When you get here, you're sure to ask, learning these two things is to draw lines and ellipses??? Surely not, or how could I write it in gu? First look at the effect:
- (void)createUI2 { // Create shapeLayer _shapeLayer = [CAShapeLayer layer]; _shapeLayer.frame = CGRectMake(0, 0, 200, 200); _shapeLayer.position = self.view.center; _shapeLayer.path = [self getStarOneBezierPath].CGPath; _shapeLayer.fillColor = [UIColor clearColor].CGColor; _shapeLayer.strokeColor = [UIColor redColor].CGColor; _shapeLayer.lineWidth = 2.0f; [self.view.layer addSublayer:_shapeLayer]; // create-timer _timer = [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(bezierPathAnimation) userInfo:nil repeats:YES]; } /// Execute bezierPath's animation - (void)bezierPathAnimation { static int i = 0; if (i++ % 2 == 0) { CABasicAnimation * circleAnim = [CABasicAnimation animationWithKeyPath:@"path"]; circleAnim.removedOnCompletion = NO; circleAnim.duration = 2; circleAnim.fromValue = (__bridge id _Nullable)([self getStarOneBezierPath].CGPath); circleAnim.toValue = (__bridge id _Nullable)([self getStarTwoBezierPath].CGPath); _shapeLayer.path = [self getStarTwoBezierPath].CGPath; [_shapeLayer addAnimation:circleAnim forKey:@"animateCirclePath"]; }else { CABasicAnimation * circleAnim = [CABasicAnimation animationWithKeyPath:@"path"]; circleAnim.removedOnCompletion = NO; circleAnim.duration = 2; circleAnim.fromValue = (__bridge id _Nullable)([self getStarTwoBezierPath].CGPath); circleAnim.toValue = (__bridge id _Nullable)([self getStarOneBezierPath].CGPath); _shapeLayer.path = [self getStarOneBezierPath].CGPath; [_shapeLayer addAnimation:circleAnim forKey:@"animateCirclePath"]; } } /// Bessel Curve 1 - (UIBezierPath *)getStarOneBezierPath { // draw star UIBezierPath * starPath = [UIBezierPath bezierPath]; [starPath moveToPoint:CGPointMake(22.5, 2.5)]; [starPath addLineToPoint:CGPointMake(28.32, 14.49)]; [starPath addLineToPoint:CGPointMake(41.52, 16.32)]; [starPath addLineToPoint:CGPointMake(31.92, 25.56)]; [starPath addLineToPoint:CGPointMake(34.26, 38.68)]; [starPath addLineToPoint:CGPointMake(22.5, 32.4)]; [starPath addLineToPoint:CGPointMake(10.74, 38.68)]; [starPath addLineToPoint:CGPointMake(13.08, 25.56)]; [starPath addLineToPoint:CGPointMake(3.48, 16.32)]; [starPath addLineToPoint:CGPointMake(16.68, 14.49)]; [starPath closePath]; return starPath; } /// Bessel Curve 2 - (UIBezierPath *)getStarTwoBezierPath { // draw star UIBezierPath * starPath = [UIBezierPath bezierPath]; [starPath moveToPoint:CGPointMake(22.5, 2.5)]; [starPath addLineToPoint:CGPointMake(32.15, 9.21)]; [starPath addLineToPoint:CGPointMake(41.52, 16.32)]; [starPath addLineToPoint:CGPointMake(38.12, 27.57)]; [starPath addLineToPoint:CGPointMake(34.26, 38.68)]; [starPath addLineToPoint:CGPointMake(22.5, 38.92)]; [starPath addLineToPoint:CGPointMake(10.74, 38.68)]; [starPath addLineToPoint:CGPointMake(6.88, 27.57)]; [starPath addLineToPoint:CGPointMake(3.48, 16.32)]; [starPath addLineToPoint:CGPointMake(12.85, 9.21)]; [starPath closePath]; return starPath; }
Reference article: UI of iOS--CAShape Layer