筆記-iOS設置圓角方法以及指定位置設圓角

更正

通過代碼以及instruments工具測試,如下更正bash

官方對離屏渲染產生性能問題也進行了優化:框架

iOS 9.0 以前UIimageView跟UIButton設置圓角都會觸發離屏渲染。工具

iOS 9.0 以後UIButton設置圓角會觸發離屏渲染,而UIImageView裏png圖片設置圓角不會觸發離屏渲染了,若是設置其餘陰影效果之類的仍是會觸發離屏渲染的。post

第一種方法:經過設置layer的屬性

代碼:性能

UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"TestImage"]];
// 只需設置layer層的兩個屬性
// 設置圓角
imageView.layer.cornerRadius = 50;
// 將多餘的部分切掉
imageView.layer.masksToBounds = YES;
[self.view addSubview:imageView];
複製代碼

這個方法裏maskToBounds會觸發離屏渲染,GPU在當前屏幕緩衝區外新開闢了一個渲染緩衝區進行工做,也就是離屏渲染,這會給咱們帶來額外的性能損耗,若是這樣的圓角操做達到必定數量,會觸發緩衝區的頻繁合併和上下文的頻繁切換,性能的代價會宏觀的表如今用戶體驗上<掉幀>。測試

第二種方法:使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角

代碼:優化

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
 imageView.image = [UIImage imageNamed:@"TestImage.jpg"];
 // 開始對imageView進行畫圖
 UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 0.0);
 // 使用貝塞爾曲線畫出一個圓形圖
 [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip];
 [imageView drawRect:imageView.bounds];
 imageView.image = UIGraphicsGetImageFromCurrentImageContext();
 // 結束畫圖
 UIGraphicsEndImageContext();
 [self.view addSubview:imageView];
複製代碼
  • UIGraphicsBeginImageContextWithOption(CGSize size, BOOL opaque, CGFloat scale)各參數的含義:
  • size ---新建立的文圖上下文大小
  • opaque --- 透明開關,若是圖形徹底不用透明,設置爲YES以優化位圖的存儲。
  • scale --- 縮放因子。雖然這裏能夠用[UIScreen mainScreen].scale來獲取,但實際上設爲0後,系統會自動設置正確的比例

第三種方法: 使用Core Graphics框架畫出一個圓角

代碼:spa

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 100, 100)];
imageView.image = [UIImage imageNamed:@"TestImage.jpg"];

// 開始對imageView進行畫圖
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 0.0);

// 獲取圖形上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();

// 設置一個範圍
CGRect rect = CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height);

// 根據一個rect建立一個橢圓
CGContextAddEllipseInRect(ctx, rect);

// 裁剪
CGContextClip(ctx);

// 講原照片畫到圖形上下文
[imageView.image drawInRect:rect];

// 從上下文上獲取裁剪後的照片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

// 關閉上下文
UIGraphicsEndImageContext();
imageView.image = image;
[self.view addSubview:imageView];
複製代碼

第四種方法: 使用CAShapeLayer和UIBezierPath設置圓角

代碼:3d

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 100, 100)];
imageView.image = [UIImage imageNamed:@"TestImage.jpg"];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds byRoundingCorners:UIRectCornerAllCorners
cornerRadii:imageView.bounds.size];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
// 設置大小
maskLayer.frame = imageView.bounds;
// 設置圖形樣子
maskLayer.path = maskPath.CGPath;
imageView.layer.mask = maskLayer;
[self.view addSubview:imageView];
複製代碼

指定須要的角成爲圓角(第四種方法的延伸)

方法:code

+ (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect
                          byRoundingCorners:(UIRectCorner)corners
                                cornerRadii:(CGSize)cornerRadii;
                                
corners參數指定了要成爲圓角的角, 枚舉類型以下:
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
    UIRectCornerTopLeft     = 1 <&lt; 0,
    UIRectCornerTopRight    = 1 <&lt; 1,
    UIRectCornerBottomLeft  = 1 <&lt; 2,
    UIRectCornerBottomRight = 1 <&lt; 3,
    UIRectCornerAllCorners  = ~0UL
};

複製代碼

實現代碼:

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 200, 200, 200)];
imageView.image = [UIImage imageNamed:@"TestImage.jpg"];

// 繪製圓角 需設置的圓角 使用"|"來組合
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds byRoundingCorners:UIRectCornerTopLeft |
UIRectCornerBottomRight cornerRadii:CGSizeMake(30, 30)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];

// 設置大小
maskLayer.frame = imageView.bounds;

// 設置圖形樣子
maskLayer.path = maskPath.CGPath;
imageView.layer.mask = maskLayer;
[self.view addSubview:imageView];
複製代碼

效果圖:

網上不少說,第四種方法最好,對內存的消耗最少,並且渲染快速。
實際測試以後,結果是不同的,具體能夠參考筆記-圓角四種方法的對比以及性能檢測

相關文章
相關標籤/搜索