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

那怎样去实现?

通常图片都是矩形的,假设想在client去实现不规则的头像,须要自己去实现。

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 + 2 *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 + 2 * radius, origin.y, origin.x + 2 * radius, origin.y + radius, radius);CGPathAddArcToPoint(path, NULL, origin.x + 2 * radius, origin.y + 2 * radius, origin.x + radius, origin.y + 2  * radius, radius);CGPathAddLineToPoint(path, NULL, origin.x, origin.y + 2 * 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:@"gray_bubble_right@2x.png"].CGImage;_contentLayer = [CALayer layer];_contentLayer.mask = _maskLayer;_contentLayer.frame = self.bounds;[self.layer addSublayer:_contentLayer];

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

不停的改变CALayer的一个坏处就是很的损耗性能,假设你有一个cell的列表。每一个列表有个头像的话。高速滑动的时候。你会发现很的卡。

此时理想的解决方式是使用CGPath或者UIBezierPath构建不规则的path,然后clip画出来。这里就不具体解说了。

演示样例代码例如以下:

- (UIImage *)maskImage
{// start with an imageUIImage * fooImage = self;//[UIImage imageNamed:@"foo.png"];CGRect imageRect = CGRectMake(0, 0, fooImage.size.width, fooImage.size.height);// set the implicit graphics context ("canvas") to a bitmap context for imagesUIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);// create a bezier path defining rounded cornersUIBezierPath * path = [UIBezierPath bezierPathWithRect:imageRect];CGFloat radius = fooImage.size.width / 2.5;CGFloat _radius = radius;//construct your shaped path[path moveToPoint:CGPointMake(0, 0)];[path addArcWithCenter:CGPointMake(radius, radius) radius:_radius startAngle:M_PI endAngle:3 * M_PI / 2 clockwise:TRUE];[path moveToPoint:CGPointMake(fooImage.size.width, 0)];[path addArcWithCenter:CGPointMake(fooImage.size.width - radius, radius) radius:_radius startAngle:3 * M_PI / 2 endAngle:2 * M_PI clockwise:TRUE];[path moveToPoint:CGPointMake(fooImage.size.width, fooImage.size.height)];[path addArcWithCenter:CGPointMake(fooImage.size.width - radius, fooImage.size.height - radius) radius:_radius startAngle:0 endAngle:M_PI / 2 clockwise:TRUE];[path moveToPoint:CGPointMake(0, fooImage.size.height)];[path addArcWithCenter:CGPointMake(radius, fooImage.size.height - radius) radius:_radius startAngle:M_PI / 2 endAngle:M_PI clockwise:TRUE];path.flatness = 1000;path.lineCapStyle = kCGLineCapRound;path.lineJoinStyle = kCGLineJoinRound;// use this path for clipping in the implicit context[path addClip];// draw the image into the implicit context[fooImage drawInRect:imageRect];// save the clipped image from the implicit context into an imageUIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();// cleanupUIGraphicsEndImageContext();return maskedImage;
}

源码

转载于:https://www.cnblogs.com/yxwkf/p/5244758.html

iOS 不规则的ImageView相关推荐

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

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

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

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

  3. 2019 下半年 Flutter 实现的性能优化 | 英雄榜

    作者 / Yuqian Li & Shams Zakhour 高性能是 Flutter 的关键特性之一.我们希望通过本文着重分享在 2019 年下半年由整个 Flutter 社群实现的性能优化 ...

  4. iOS图片不规则剪切

    最近项目中需求中增加了一个聊天图片剪切成不规则的要求,查看了一下相关资料.结果用iOS SDK自带的API就可以实现如下这个效果. // 传进去一个UIView进行绘制,返回一个 CAShapeLay ...

  5. ios button.imageview 和setimage的区别

    UIButton的imageView属性是readonly,是不可写的. 所以要给button设置图片,必须要用他提供的方法 imageForState:(图片保持原大小,会遮挡title) 或者 b ...

  6. iOS imageview图片压缩变形

    http://www.cnblogs.com/someonelikeyou/p/4803406.html imageView.contentMode = UIViewContentModeScaleA ...

  7. android菱形imageview,ios – 在UICollectionView中,UIImageView应该是圆形视图而不是菱形...

    我有UICollectionView和UI ImageView(如图所示). 我想把它作为圆形视图.但是,当我运行应用程序时,它显示为菱形(下图). 在(UICollectionViewCell *) ...

  8. ios uiview 如何刷新_ios-如何在Swift中刷新imageview而无需重新加载页面?

    我有一个更新照片按钮,该按钮连接到facebookgraphAPI并下载当前用户的个人资料图片. 我希望刷新视图上的图像,而无需重新加载viewController. 有什么办法可以做到这一点?我知道 ...

  9. android imageview 上蒙版,在iOS中为UIImageView的圆形蒙版设置动画

    马特有正确的想法 . 你想要做的是使用Core Animation和CAShapeLayer . 图层具有可选的蒙版属性,该属性控制可见的图层部分 . 您可以添加CAShapeLayer作为另一个图层 ...

  10. IOS开发中--点击imageView上的Button没有任何反应

    点击imageView上的Button没有任何反应:     解决方法:设置图片的userInteractionEnabled为YES,使该imageView可以与用户进行交互 转载于:https:/ ...

最新文章

  1. postgresql 查询序列_时间序列数据库(TSDB)初识与选择
  2. 99. 恢复二叉搜索树
  3. k8s多master建议用几个_K8s 还是 k3s?This is a question
  4. HBase总结(二十)HBase常用shell命令详细说明
  5. Gradle 简单使用
  6. 杭电2066一个人的旅行
  7. pfSense添加子网的几种方式
  8. 什么原数据更容易平稳_为什么老年人更容易患上艾滋病?
  9. 语音识别人工智能解决方案
  10. python在信号处理的应用_Python和信号处理程序
  11. JAVASSM框架面试题
  12. 程序员自编的中华古诗词数据库在GitHub上火了!
  13. 细说SDRAM控制器
  14. phpstudy安装yar扩展
  15. 使用 ATS605LSG 的电动机驱动的磁体编码器设计
  16. Linux 网络包接收过程的监控与调优
  17. 9V充3.7V锂电池,12V充3.7V单节锂电池充电芯片和电路图
  18. Hibernate投入JBoss怀抱
  19. C++(学习) —— Vector容器,类的静态成员的使用练习(Singer类)
  20. java.lang.IllegalStateException: No instances www.xxxx.com available for localhost

热门文章

  1. 九九乘法表新打表(倒三角式)
  2. 【2019银川网络赛D:】Take Your Seat(概率--递推+思维)
  3. 【算法笔记】输出字符串的所有子序列
  4. IntelliJ IDEA 查看类结构,查看类图,继承关系,查看package包关系
  5. 极客大学架构师训练营 框架设计、设计原则、设计模式 第四课 听课总结
  6. 2021-09-03 DeepMatch 推荐系统
  7. 187.重复的DNA序列
  8. 简述deque容器的插入删除原理
  9. 360云盘会不会停止服务器,360云盘能否继续使用啊?
  10. 凸优化第五章对偶 5.3几何解释