zoukankan      html  css  js  c++  java
  • iOS 不规则的ImageView

    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, 代码如下:

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

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

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

    如果将代码改成

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    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.   
    9. _contentLayer = [CALayer layer];  
    10. _contentLayer.mask = _maskLayer;  
    11. _contentLayer.frame = self.bounds;  
    12. [self.layer addSublayer:_contentLayer];  

    的效果:

    如果将代码改成:

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    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.   
    7. CGPathAddArcToPoint(path, NULL, origin.x, origin.y, origin.x + radius, origin.y, radius);  
    8. CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y, origin.x + 22 * radius, origin.y + radius, radius);  
    9. CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y + 22 * radius, origin.x + radius, origin.y + 2  * radius, radius);  
    10. CGPathAddLineToPoint(path, NULL, origin.x, origin.y + 22 * radius);  
    11.   
    12. _maskLayer = [CAShapeLayer layer];  
    13. _maskLayer.path = path;  
    14. _maskLayer.fillColor = [UIColor blackColor].CGColor;  
    15. _maskLayer.strokeColor = [UIColor clearColor].CGColor;  
    16. _maskLayer.frame = self.bounds;  
    17. _maskLayer.contentsCenter = CGRectMake(0.5, 0.5, 0.1, 0.1);  
    18. _maskLayer.contentsScale = [UIScreen mainScreen].scale;                 //非常关键设置自动拉伸的效果且不变形  
    19.   
    20. _contentLayer = [CALayer layer];  
    21. _contentLayer.mask = _maskLayer;  
    22. _contentLayer.frame = self.bounds;  
    23. [self.layer addSublayer:_contentLayer];  

    将是这个效果:

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

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

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

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
     
    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.   
    9. _contentLayer = [CALayer layer];  
    10. _contentLayer.mask = _maskLayer;  
    11. _contentLayer.frame = self.bounds;  
    12. [self.layer addSublayer:_contentLayer];  
    
    

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

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

  • 相关阅读:
    Python基础之subprocess
    Python基础之读取ini文件
    Python如何将py文件打包成exe
    C++第四十一篇 -- 安装成功的第一个驱动文件
    C++第四十篇 -- 研究一下Windows驱动开发(三)-- NT式驱动的基本结构
    C++第三十九篇 -- 研究一下Windows驱动开发(二)-- 驱动程序中重要的数据结构
    C++第三十八篇 -- 研究一下Windows驱动开发(二)--WDM式驱动的加载
    C++第三十七篇 -- 调试驱动程序
    iis提示“另一个程序正在使用此文件,进程无法访问。(异常来自HRESULT:0x80070020) ”解决办法
    Serv-U无法上传“中文文件夹”的问题(没有权限)
  • 原文地址:https://www.cnblogs.com/apem/p/4870666.html
Copyright © 2011-2022 走看看