CAShapeLayer是CALayer的子类,但是比CALayer更灵活,配合一个神奇的属性path用这个属性配合上 UIBezierPath 这个类就可以达到超神的效果。
玩一下 UIBezierPath
UIBezierPath 顾名思义,这是用贝塞尔曲线的方式来构建一段弧线,你可以用任意条弧线来组成你想要的形状,它包含起始点、终点、及控制点三个参数。如下图红色矩形范围内的白色背景,最上面就是一条有弧度的曲线。

它可以用 CAShapeLayer+UIBezierPath 来做,思路大概是这样,先移动到左上方的位置,然后向下划线,然后往右划线,然后往上划线,还剩一个盖子,这个盖子就用一个控制点控制曲率,非常简单,图中的红色点即为控制点,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| -(void)initLayer { CAShapeLayer *layer = [[CAShapeLayer alloc] init]; UIBezierPath *path = [[UIBezierPath alloc] init]; [path moveToPoint:CGPointMake(0, SCREEN_HEIGHT - MENU_HEIGHT)]; [path addLineToPoint:CGPointMake(0, SCREEN_HEIGHT)]; [path addLineToPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT)]; [path addLineToPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT - MENU_HEIGHT)]; [path addQuadCurveToPoint:CGPointMake(0, SCREEN_HEIGHT - MENU_HEIGHT) controlPoint:CGPointMake(SCREEN_WIDTH/2.f, SCREEN_HEIGHT - MENU_HEIGHT * 2.0f)]; layer.path = path.CGPath; layer.fillColor = [UIColor purpleColor].CGColor; layer.strokeColor = [UIColor blueColor].CGColor; layer.lineWidth = 1.f; [self.view.layer addSublayer:layer]; }
|
效果如图:

使用 UIBezierPath 画圆及添加加载动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| -(void)initCircle { CAShapeLayer *layer = [[CAShapeLayer alloc] init]; UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)]; layer.path = path.CGPath; layer.fillColor = [UIColor clearColor].CGColor; layer.strokeColor = [UIColor blueColor].CGColor; layer.lineWidth = 1.f; layer.strokeStart = 0; layer.strokeEnd = 0.75; layer.frame = CGRectMake(0, 0, 200, 200); layer.position = self.view.center; [self.view.layer addSublayer:layer]; CABasicAnimation *animation = [[CABasicAnimation alloc] init]; animation.fromValue = [NSNumber numberWithFloat:1.0]; animation.toValue = [NSNumber numberWithFloat:0.0]; animation.duration = 5.f; [layer addAnimation:animation forKey:@"strokeStart"]; }
|
利用 layer 的 mask 属性为图片添加遮罩
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| -(void)showImage { UIImage *image = BHIMG(@"sunyizhen.jpg"); UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; imageView.contentMode = UIViewContentModeCenter; imageView.mj_y = kNavBarHeight; [self.view addSubview:imageView]; UIBezierPath *originPath = [UIBezierPath bezierPathWithRect:CGRectInset(imageView.bounds, 67.f, 91.5f)]; UIBezierPath *finalPath = [UIBezierPath bezierPathWithRect:imageView.bounds]; CAShapeLayer *layer = [CAShapeLayer layer]; layer.path = finalPath.CGPath; imageView.layer.mask = layer; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"]; animation.fromValue = (__bridge id _Nullable)(originPath.CGPath); animation.toValue = (__bridge id _Nullable)(finalPath.CGPath); animation.duration = 2.f; [layer addAnimation:animation forKey:@"path"]; }
|
效果如下

最后
总之使用 UIbezierPath 和 CAShapeLayer 可以画出你想要的任何形状,没有它做不到,只有你想不到,当然有时候可能会比较复杂而显得比较笨拙,但最终实现后确实会显得很有趣。
代码可以下载GITHUB中BlogDemo进行查看。