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

iOS 不规则的ImageView的更多相关文章

  1. iOS开发之ImageView复用实现图片无限轮播

    在上篇博客中iOS开发之多图片无缝滚动组件封装与使用给出了图片无限轮播的实现方案之一,下面在给出另一种解决方案.今天博客中要说的就是在ScrollView上贴两个ImageView, 把ImageVi ...

  2. iOS 设置图片imageView圆角——对图片进行裁剪

    以前设置图片圆角总是把imageView设置成圆形,然后设置maskToBounds为YES,其实这样处理很消耗性能,图片多了之后比较卡,最好将图片进行裁剪后显示:这里有个分类可以用: UIImage ...

  3. iOS开发——给ImageView添加点击事件

          给ImageView添加点击事件   1: cell.pictureView.userInteractionEnabled = YES; 2: UITapGestureRecognizer ...

  4. iOS -实现imageView中的button响应点击事件的方法

    <pre name="code" class="cpp" style="font-size: 13px;">/** imagev ...

  5. IOS 多个ImageView图片层叠透明区域点击事件穿透

    经常用到多个透明图片层叠,但又需要获取不同图片的点击事件,本文实现图片透明区域穿透点击事件 实现人体各个部位点击 - (BOOL) pointInside:(CGPoint)point withEve ...

  6. iOS OC利用imageview属性切出类似圆柱图形

    效果一: 效果二: 上边的图形我也数不出来名字,,暂称圆柱正切图形吧,看到这样的需求似不似在想各种插件,各种切图方法了呢... UIImageView的属性可以轻松搞定 UIViewContentMo ...

  7. 我的iOS开发系列博文

    之前目录性的总结了发表过的关于OC方面的文章,今天在目录性的总结一下有关iOS开发的文章.走过路过不要错过哦,今天的博文也全都是干货.写技术博客与大家交流一下思想也是不错的. 下面是我的技术博客中有关 ...

  8. fir.im Weekly - 94 个 iOS 开发资源推荐

    距离 2016 年还有 17 个日夜,而你和回家只隔了一张 12306 验证码的距离,祝大家抢票顺利.本期 fir.im Weekly 收集了一些优秀的 GitHub 源码.开发工具和动画特效,希望对 ...

  9. Android ImageView图片透明区域不响应点击事件,不规则图片透明区域响应点击事件

    转载:http://blog.csdn.net/aminfo/article/details/7872681 经常会在项目中用到透明图片,不规则图片,特别是做游戏的时候,需要对图片的透明区域的点击事件 ...

随机推荐

  1. FCC上的初级算法题

    核心提示:FCC的算法题一共16道.跟之前简单到令人发指的基础题目相比,难度是上了一个台阶.主要涉及初步的字符串,数组等运算.仍然属于基础的基础,官方网站给出的建议完成时间为50小时,超出了之前所有非 ...

  2. C#----XML操作小结

    结点和元素的区别: * 结点和元素的区别:  * 结点包括元素,结点可以是一个文本,也可以是一个属性,结点包括的类型在XmlNodeType中总结.  * <root id="这是一个 ...

  3. yourphp添加KindEditor编辑器

    <tr> <td align="right">故障描述</td> <script charset="utf-8" sr ...

  4. PHP file_get_contents设置超时处理方法

    从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_c ...

  5. Python之路【第十六篇续】Django进阶篇

    Django请求生命周期 首先:对于所有的web框架来说本质就是一个socket服务端,浏览器是socket客户端 路由系统 在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规 ...

  6. 修改hosts

  7. jQuery 取值、赋值的基本方法

    转载:http://www.cnblogs.com/huanhuan86/archive/2012/06/13/2548071.html 获取元素的value值: /*获得TEXT.AREATEXT的 ...

  8. vi和vim区别及命令详解

    vi和vim都是Linux中的编辑器,不同的是vim比较高级,可以视为vi的升级版本.vi使用于文本编辑,但是vim更适用于coding.     现将vim的命令行收集于下: vi有3个模式:插入模 ...

  9. SQL Server2008 表旋转(pivot)技术

    参考资料: http://www.cnblogs.com/xiashengwang/p/3503554.html

  10. for while (list each)的用法

    each是返回数组 指针当前指向的 元素的 索引和值: 索引有四个值: 0, 1, key, value. 0和key是一样的, 1和value是一样的 但是each只是将数组指针 向前移动 一步, ...