国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS 不規則的ImageView

2019-11-09 16:47:17
字體:
來源:轉載
供稿:網友

http://blog.csdn.net/johnzhjfly/article/details/41175015?utm_source=tuicool&utm_medium=referral

我們在做iOS開發的時候,往往需要實現不規則形狀的頭像,如:

那如何去實現?

通常圖片都是矩形的,如果想在客戶端去實現不規則的頭像,需要自己去實現。

1.使用layer去實現, 見http://blog.csdn.net/johnzhjfly/article/details/39993345

2.使用CAShapeLayer, CALayer如何去實現

我們來看看如何使用CAShapeLayer去實現,

定義一個ShapedImageView,繼承于UIView, 代碼如下:

[objc] view plain copy 在CODE上查看代碼片#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,%20CAShapedLayer有個path的屬性,將內容Layer的mask設置為maskLayer,%20就可以獲取到我們想要的形狀。

path我們可以使用CAMutablePath任意的構造,上述的代碼運行想過如下:

如果將代碼改成

[objc] view plain copy 在CODE上查看代碼片_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];  的效果:

如果將代碼改成:

[objc] view plain copy 在CODE上查看代碼片CGMutablePathRef path = CGPathCreateMutable();  CGPoint origin = self.bounds.origin;  CGFloat radius = CGRectGetWidth(self.bounds) / 2;  CGPathMoveToPoint(path, NULL, origin.x, origin.y + 22 *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 + 22 * radius, origin.y, origin.x + 22 * radius, origin.y + radius, radius);  CGPathAddArcToPoint(path, NULL, origin.x + 22 * radius, origin.y + 22 * radius, origin.x + radius, origin.y + 2  * radius, radius);  CGPathAddLineToPoint(path, NULL, origin.x, origin.y + 22 * 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呢?答案是肯定的,代碼如下:

[objc] view plain copy 在CODE上查看代碼片_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畫出來,這里就不詳細講解了。示例代碼如下:

[objc] view plain copy 在CODE上查看代碼片- (UIImage *)maskImage  {      // start with an image      UIImage * 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 images      UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);      // create a bezier path defining rounded corners      UIBezierPath * 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:33 * M_PI / 2 clockwise:TRUE];      [path moveToPoint:CGPointMake(fooImage.size.width, 0)];      [path addArcWithCenter:CGPointMake(fooImage.size.width - radius, radius) radius:_radius startAngle:33 * M_PI / 2 endAngle:22 * 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 image      UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();      // cleanup      UIGraphicsEndImageContext();      return maskedImage; 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 河北省| 洛扎县| 怀远县| 台南县| 长宁区| 遂昌县| 张家口市| 闻喜县| 洛宁县| 读书| 台南市| 吴江市| 巴东县| 泽州县| 齐齐哈尔市| 嘉定区| 中阳县| 丹寨县| 什邡市| 吉首市| 宁蒗| 刚察县| 克东县| 穆棱市| 香格里拉县| 中牟县| 海盐县| 遵义县| 邢台县| 怀宁县| 晋江市| 临海市| 罗山县| 恩平市| 金坛市| 德钦县| 定西市| 启东市| 长宁区| 多伦县| 景东|