先上效果图
再上源码
给UIView添加一个Category方法
/// 添加圆角正多边形遮罩
/// @param viewWidth 当前视图宽度
/// @param edgeCount 多边形边数
/// @param rotationAngle 旋转角度
/// @param cornerRadius 圆角半径(0 - cos(M_PI / edgeCount) * viewWidth)
- (void)addRoundedPolygonMaskWithViewWidth:(CGFloat)viewWidth edgeCount:(NSInteger)edgeCount rotationAngle:(CGFloat)rotationAngle cornerRadius:(CGFloat)cornerRadius {
NSAssert(viewWidth > 0, @"viewWidth出错");
NSAssert(edgeCount >= 3, @"edgeCount出错");
NSAssert(cornerRadius >= 0, @"cornerRadius出错");
NSAssert(cornerRadius / viewWidth <= cos(M_PI / edgeCount), @"cornerRadius出错");
CGFloat viewRadius = viewWidth / 2.0;
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat angleCoefficient = M_PI / 180.0;
CGFloat averageAngle = M_PI / edgeCount;
CGFloat averageAngle2 = 360.0 / edgeCount;
if (cornerRadius) {
for (int i = 0; i < edgeCount; i++) {
CGFloat angle = (rotationAngle + averageAngle2 / 2.0 + i * averageAngle2) * angleCoefficient;
CGFloat centerRadius = viewRadius - cornerRadius / sin(M_PI_2 - averageAngle);
CGFloat tempSide1 = sin(averageAngle) * centerRadius;
CGFloat tempSide2 = cos(averageAngle) * viewRadius;
CGFloat pointRadius = sqrt(tempSide1 * tempSide1 + tempSide2 * tempSide2);
CGFloat pointAngle = averageAngle - atan(tempSide1 / tempSide2);
CGPoint point = CGPointMake(viewRadius - pointRadius * sin(angle - pointAngle), viewRadius + pointRadius * cos(angle - pointAngle));
CGPoint centerPoint = CGPointMake(viewRadius - centerRadius * sin(angle), viewRadius + centerRadius * cos(angle));
CGFloat startAngle = (90 + rotationAngle + i * averageAngle2) * angleCoefficient;
if (i) {
[path addLineToPoint:point];
} else {
[path moveToPoint:point];
}
[path addArcWithCenter:centerPoint radius:cornerRadius startAngle:startAngle endAngle:startAngle + averageAngle * 2 clockwise:YES];
}
} else {
for (int i = 0; i < edgeCount; i++) {
CGFloat angle = (rotationAngle + averageAngle2 / 2.0 + i * averageAngle2) * angleCoefficient;
CGPoint point = CGPointMake(viewRadius * (1 - sin(angle)), viewRadius * (1 + cos(angle)));
if (i) {
[path addLineToPoint:point];
} else {
[path moveToPoint:point];
}
}
}
[path closePath];
CAShapeLayer *shapLayer = [CAShapeLayer layer];
shapLayer.path = path.CGPath;
self.layer.mask = shapLayer;
}
最后上测试用例
先添加两张图片,一个背景,一个头像(效果在头像上,背景不是必要的,只是为了形成明显对比才加的背景)
UIImageView *back = [[UIImageView alloc] init];
back.image = [UIImage imageNamed:@"back"];
back.frame = CGRectMake(0, 0, 375, 667);
[self.view addSubview:back];
UIImageView *header = [[UIImageView alloc] init];
header.image = [UIImage imageNamed:@"header"];
header.frame = CGRectMake(100, 300, 175, 175);
[self.view addSubview:header];
上面效果图中四个正三角形对应的方法
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:3 rotationAngle:0 cornerRadius:0];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:3 rotationAngle:0 cornerRadius:10];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:3 rotationAngle:0 cornerRadius:20];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:3 rotationAngle:60 cornerRadius:10];
上面效果图中四个正方形对应的方法
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:4 rotationAngle:0 cornerRadius:0];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:4 rotationAngle:0 cornerRadius:10];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:4 rotationAngle:0 cornerRadius:20];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:4 rotationAngle:45 cornerRadius:20];
上面效果图中四个正五边形对应的方法
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:5 rotationAngle:0 cornerRadius:0];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:5 rotationAngle:0 cornerRadius:10];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:5 rotationAngle:0 cornerRadius:20];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:5 rotationAngle:36 cornerRadius:20];
上面效果图中四个正六边形对应的方法
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:6 rotationAngle:0 cornerRadius:0];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:6 rotationAngle:0 cornerRadius:10];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:6 rotationAngle:0 cornerRadius:20];
[header addRoundedPolygonMaskWithViewWidth:175 edgeCount:6 rotationAngle:30 cornerRadius:20];
当然,也可以自由发挥做出像下面这样的动效