我们在做iOS开发的时候,往往需要实现不规则形状的头像,如:
那如何去实现?
通常图片都是矩形的,如果想在客户端去实现不规则的头像,需要自己去实现。
1.使用layer去实现, 见http://blog.csdn.net/johnzhjfly/article/details/39993345
2.使用CAShapeLayer, CALayer如何去实现
我们来看看如何使用CAShapeLayer去实现,
定义一个ShapedImageView,继承于UIView, 代码如下:
- #import "ShapedImageView.h"
-
- @interface ShapedImageView()
- {
- CALayer *_contentLayer;
- CAShapeLayer *_maskLayer;
- }
- @end
-
- @implementation ShapedImageView
-
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- [self setup];
- }
- return self;
- }
-
- - (void)setup
- {
- _maskLayer = [CAShapeLayer layer];
- _maskLayer.path = [UIBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;
- _maskLayer.fillColor = [UIColor blackColor].CGColor;
- _maskLayer.strokeColor = [UIColor redColor].CGColor;
- _maskLayer.frame = self.bounds;
- _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
- _maskLayer.contentsScale = [UIScreen mainScreen].scale;
-
- _contentLayer = [CALayer layer];
- _contentLayer.mask = _maskLayer;
- _contentLayer.frame = self.bounds;
- [self.layer addSublayer:_contentLayer];
-
- }
-
- - (void)setImage:(UIImage *)image
- {
- _contentLayer.contents = (id)image.CGImage;
- }
-
- @end
声明了用于maskLayer个CAShapedLayer, CAShapedLayer有个path的属性,将内容Layer的mask设置为maskLayer, 就可以获取到我们想要的形状。
path我们可以使用CAMutablePath任意的构造,上述的代码运行想过如下:
如果将代码改成
- _maskLayer = [CAShapeLayer layer];
- _maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:20].CGPath;
- _maskLayer.fillColor = [UIColor blackColor].CGColor;
- _maskLayer.strokeColor = [UIColor redColor].CGColor;
- _maskLayer.frame = self.bounds;
- _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
- _maskLayer.contentsScale = [UIScreen mainScreen].scale;
-
- _contentLayer = [CALayer layer];
- _contentLayer.mask = _maskLayer;
- _contentLayer.frame = self.bounds;
- [self.layer addSublayer:_contentLayer];
的效果:
如果将代码改成:
- CGMutablePathRef path = CGPathCreateMutable();
- CGPoint origin = self.bounds.origin;
- CGFloat radius = CGRectGetWidth(self.bounds) / 2;
- CGPathMoveToPoint(path, NULL, origin.x, origin.y + 22 *radius);
- CGPathMoveToPoint(path, NULL, origin.x, origin.y + radius);
-
- CGPathAddArcToPoint(path, NULL, origin.x, origin.y, origin.x + radius, origin.y, radius);
- CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y, origin.x + 22 * radius, origin.y + radius, radius);
- CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y + 22 * radius, origin.x + radius, origin.y + 2 * radius, radius);
- CGPathAddLineToPoint(path, NULL, origin.x, origin.y + 22 * radius);
-
- _maskLayer = [CAShapeLayer layer];
- _maskLayer.path = path;
- _maskLayer.fillColor = [UIColor blackColor].CGColor;
- _maskLayer.strokeColor = [UIColor clearColor].CGColor;
- _maskLayer.frame = self.bounds;
- _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
- _maskLayer.contentsScale = [UIScreen mainScreen].scale;
-
- _contentLayer = [CALayer layer];
- _contentLayer.mask = _maskLayer;
- _contentLayer.frame = self.bounds;
- [self.layer addSublayer:_contentLayer];
将是这个效果:
理论上我们可以构造出任意想要的形状,但是有些形状如果你不熟悉几何知识的话是构造不出正确的
path的,从代码上我们可以看到我们可以通过设置CALayer的contents属性来设置显示的内容,那我们
是不是可以通过设置CAShapedLayer的contents来设置maskLayer呢?答案是肯定的,代码如下:
- _maskLayer = [CAShapeLayer layer];
- _maskLayer.fillColor = [UIColor blackColor].CGColor;
- _maskLayer.strokeColor = [UIColor clearColor].CGColor;
- _maskLayer.frame = self.bounds;
- _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
- _maskLayer.contentsScale = [UIScreen mainScreen].scale;
- _maskLayer.contents = (id)[UIImage imageNamed:@"[email protected]"].CGImage;
-
- _contentLayer = [CALayer layer];
- _contentLayer.mask = _maskLayer;
- _contentLayer.frame = self.bounds;
- [self.layer addSublayer:_contentLayer];
gray_bubble_right就是你想要的形状,运行效果如下:
源代码:https://github.com/heavensword/ShapedImageView