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. Javascript 与正则表达式

    一.正则表达式(regular expression简称res) 二.元字符及其在正则表达式上下文中的行为 三.正则表达式的常用方法 四.与正则表达式有关的字符串对象的方法 五.常用的正则表达式的操作 ...

  2. 爬虫3 html解析器 html_parser.py

    #coding:utf8 import urlparse from bs4 import BeautifulSoup import re __author__ = 'wang' class HtmlP ...

  3. Interesting things in Unity 4.5 you probably didn't know about

    http://va.lent.in/interesting-things-in-unity-4-5-you-probably-didnt-know-about/

  4. CSS 控制Html页面高度导致抖动问题的原因

    CSS 控制Html页面高度导致抖动,这类由高度导致页面抖动的问题,其实究其根本原因是滚动条是否显示导致的 在CSS中添加如下代码: html,body{ overflow-y:scroll;} ht ...

  5. 要引用这几个才有GetOwinContext与GetAutofacLifetimeScope

    using Owin; using Autofac; using Autofac.Integration.Owin; using System.Web; var owin = this.Request ...

  6. JQuery.getJSON 从aspx页面返回JSON数据

    public partial class WebForm2 : System.Web.UI.Page { protected void Page_Load(object sender, EventAr ...

  7. fibonacci 数列及其应用

    fibonacci 数列及其延展 fibonacci计算 fibonacci数列是指 0,1,1,2,3,5,8,13,21……这样自然数序列,即从第3项开始满足f(n)=f(n-1)+f(n-2): ...

  8. Python之路【第十一篇续】前端初识之CSS

    css解释 css样式: css是英文Cascading Style Sheets的缩写,称为层叠样式表,用于对页面进行美化,CSS的可以使页面更加的美观.基本上所有的html页面都或多或少的使用cs ...

  9. iOS静态库小结--(yoowei)

    准备知识: 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.根据源代码的公开情况,库可以分为2种类型 a.开源库 公开源代码,能看到具体实现 ,比如SDWebImage.AFNetw ...

  10. asp.net MVC动态路由

    项目中遇到需要动态生成控制器和视图的. 于是就折腾半天,动态生成控制器文件和视图文件,但是动态生成控制器不编译是没法访问的. 找人研究后,得到要领: 1.放在App_Code文件夹内 2.不要命名空间 ...