http://blog.csdn.net/kevinpake/article/details/41205715

我们在做iOS开发的时候,往往需要实现不规则形状的头像,如:

那如何去实现?

通常图片都是矩形的,如果想在客户端去实现不规则的头像,需要自己去实现。

1.使用layer去实现, 见http://blog.csdn.net/johnzhjfly/article/details/39993345

2.使用CAShapeLayer, CALayer如何去实现

我们来看看如何使用CAShapeLayer去实现,

定义一个ShapedImageView,继承于UIView, 代码如下:

  1. #import "ShapedImageView.h"
  2. @interface ShapedImageView()
  3. {
  4. CALayer      *_contentLayer;
  5. CAShapeLayer *_maskLayer;
  6. }
  7. @end
  8. @implementation ShapedImageView
  9. - (instancetype)initWithFrame:(CGRect)frame
  10. {
  11. self = [super initWithFrame:frame];
  12. if (self) {
  13. [self setup];
  14. }
  15. return self;
  16. }
  17. - (void)setup
  18. {
  19. _maskLayer = [CAShapeLayer layer];
  20. _maskLayer.path = [UIBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;
  21. _maskLayer.fillColor = [UIColor blackColor].CGColor;
  22. _maskLayer.strokeColor = [UIColor redColor].CGColor;
  23. _maskLayer.frame = self.bounds;
  24. _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
  25. _maskLayer.contentsScale = [UIScreen mainScreen].scale;
  26. _contentLayer = [CALayer layer];
  27. _contentLayer.mask = _maskLayer;
  28. _contentLayer.frame = self.bounds;
  29. [self.layer addSublayer:_contentLayer];
  30. }
  31. - (void)setImage:(UIImage *)image
  32. {
  33. _contentLayer.contents = (id)image.CGImage;
  34. }
  35. @end

声明了用于maskLayer个CAShapedLayer, CAShapedLayer有个path的属性,将内容Layer的mask设置为maskLayer, 就可以获取到我们想要的形状。

path我们可以使用CAMutablePath任意的构造,上述的代码运行想过如下:

如果将代码改成

  1. _maskLayer = [CAShapeLayer layer];
  2. _maskLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:20].CGPath;
  3. _maskLayer.fillColor = [UIColor blackColor].CGColor;
  4. _maskLayer.strokeColor = [UIColor redColor].CGColor;
  5. _maskLayer.frame = self.bounds;
  6. _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
  7. _maskLayer.contentsScale = [UIScreen mainScreen].scale;                 //非常关键设置自动拉伸的效果且不变形
  8. _contentLayer = [CALayer layer];
  9. _contentLayer.mask = _maskLayer;
  10. _contentLayer.frame = self.bounds;
  11. [self.layer addSublayer:_contentLayer];

的效果:

如果将代码改成:

  1. CGMutablePathRef path = CGPathCreateMutable();
  2. CGPoint origin = self.bounds.origin;
  3. CGFloat radius = CGRectGetWidth(self.bounds) / 2;
  4. CGPathMoveToPoint(path, NULL, origin.x, origin.y + 22 *radius);
  5. CGPathMoveToPoint(path, NULL, origin.x, origin.y + radius);
  6. CGPathAddArcToPoint(path, NULL, origin.x, origin.y, origin.x + radius, origin.y, radius);
  7. CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y, origin.x + 22 * radius, origin.y + radius, radius);
  8. CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y + 22 * radius, origin.x + radius, origin.y + 2  * radius, radius);
  9. CGPathAddLineToPoint(path, NULL, origin.x, origin.y + 22 * radius);
  10. _maskLayer = [CAShapeLayer layer];
  11. _maskLayer.path = path;
  12. _maskLayer.fillColor = [UIColor blackColor].CGColor;
  13. _maskLayer.strokeColor = [UIColor clearColor].CGColor;
  14. _maskLayer.frame = self.bounds;
  15. _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
  16. _maskLayer.contentsScale = [UIScreen mainScreen].scale;                 //非常关键设置自动拉伸的效果且不变形
  17. _contentLayer = [CALayer layer];
  18. _contentLayer.mask = _maskLayer;
  19. _contentLayer.frame = self.bounds;
  20. [self.layer addSublayer:_contentLayer];

将是这个效果:

理论上我们可以构造出任意想要的形状,但是有些形状如果你不熟悉几何知识的话是构造不出正确的

path的,从代码上我们可以看到我们可以通过设置CALayer的contents属性来设置显示的内容,那我们

是不是可以通过设置CAShapedLayer的contents来设置maskLayer呢?答案是肯定的,代码如下:

  1. _maskLayer = [CAShapeLayer layer];
  2. _maskLayer.fillColor = [UIColor blackColor].CGColor;
  3. _maskLayer.strokeColor = [UIColor clearColor].CGColor;
  4. _maskLayer.frame = self.bounds;
  5. _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);
  6. _maskLayer.contentsScale = [UIScreen mainScreen].scale;                 //非常关键设置自动拉伸的效果且不变形
  7. _maskLayer.contents = (id)[UIImage imageNamed:@"gray_bubble_right@2x.png"].CGImage;
  8. _contentLayer = [CALayer layer];
  9. _contentLayer.mask = _maskLayer;
  10. _contentLayer.frame = self.bounds;
  11. [self.layer addSublayer:_contentLayer];

gray_bubble_right就是你想要的形状,运行效果如下:

源代码:https://github.com/heavensword/ShapedImageView

最新文章

  1. Eenterprise linux服务器分区
  2. 10个学习Android开发的网站推荐
  3. app微信支付(一) - 微信支付基本业务流程解析
  4. bootstratp图标的使用
  5. UVA 11404 五 Palindromic Subsequence
  6. JavaWeb 6 Http
  7. Netflix Zuul 了解
  8. Linux/Centos下清理内存和Cache方法
  9. linux appear packet loss solution
  10. FastScroll(2)不分组的listview 打开fastscroll的分组提示功能
  11. SDUT 2622 最短路径(Dijkstra)
  12. Qt Style Sheets Examples(官方例子目录,很全)
  13. 一颗简单的JDBC栗子
  14. python笔记八(切片)
  15. 挥舞的手臂(mixly+二次开发)
  16. Slash and BackSlash 记忆法
  17. Codeforces 460D Little Victor and Set(看题解)
  18. 本地安装apk后直接打开,按下Home键再重新打开,然后按下返回键时页面展示错误的处理方法
  19. Web Service Client使用Microsoft WSE 2.0
  20. java判断字符串编码

热门文章

  1. Matlab小技巧
  2. mysql循环获取结果集
  3. C#中事件的使用
  4. .NET Framework源码查看及下载
  5. Java7的异常处理新特性-addSuppressed()方法等
  6. H5 使用
  7. asp.net mvc 实现博客的时间分类管理
  8. 如何理解clear的css属性?
  9. mysql update操作
  10. 结果集(result set)解释与用法