這篇文章是繼筆記-iOS設(shè)置圓角方法以及指定位置設(shè)圓角文章而寫的税肪,因為上篇文章發(fā)出來后讲坎,沒有驗證关筒,也有同行的朋友讓我給出一些測試數(shù)據(jù)來證實一下,所以這里就給出一下我個人的一些測試數(shù)據(jù)驶睦,正確是否腻格,還請大家作為參考。--------另外啥繁,我寫這個僅僅只是自己作為筆記使用菜职,原來都是放在草稿里的,但是手機版的無法查看草稿旗闽,所以就發(fā)出來酬核,沒有想過會有人來看,所以如果有錯誤的內(nèi)容誤導(dǎo)了大家請原諒适室,也請發(fā)現(xiàn)錯誤的猿友及時幫忙提出嫡意,謝謝大家。
Core Animation工具檢測離屏渲染
對離屏渲染的檢測捣辆,蘋果為我們提供了一個測試工具Core Animation蔬螟。可以在Xcode->Open Develeper Tools->Instruments中找到汽畴。
先看看第一種方式:通過設(shè)置layer的屬性
對UIImageview設(shè)置:
結(jié)果: 無離屏渲染
滾動的幀率:
結(jié)果: 接近60旧巾,趨于穩(wěn)定
對UIButton設(shè)置:
結(jié)果: 離屏渲染
滾動的幀率:
如果低于40幀每秒,普通用戶就會察覺明顯的不流暢忍些,現(xiàn)在這樣app進入垃圾級別體驗了鲁猩。
對于文本視圖實現(xiàn)圓角(UILabel, UIView, UITextField, UITextView
)
均只進行cornerRadius
設(shè)置,不進行masksToBounds
的設(shè)置
離屏渲染情況:
從上圖可以看出罢坝,對于UILabel, UIView, UITextField
來說廓握,實現(xiàn)了圓角的設(shè)置,并沒有產(chǎn)生離屏渲染嘁酿;而對于UITextView
隙券,產(chǎn)生了離屏渲染。
滾動的幀率:
不存在UITextView
視圖的情況下
存在UITextView
視圖的情況下
官方對離屏渲染產(chǎn)生性能問題也進行了優(yōu)化:
iOS9.0之前UIImageView跟UIButton設(shè)置圓角都會觸發(fā)離屏渲染闹司。
iOS9.0之后UIButton設(shè)置圓角會觸發(fā)離屏渲染娱仔,而UIImageView設(shè)置圓角不會觸發(fā)離屏渲染了,但是如果設(shè)置其他陰影效果之類的還是會觸發(fā)離屏渲染
第二種方式:使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個圓角
對UIImageview設(shè)置:
幀率結(jié)果:
對UIButton設(shè)置:
幀率結(jié)果:
兩種設(shè)置均是無離屏渲染
第三種方式:使用Core Graphics框架畫出一個圓角
對UIImageview設(shè)置:
幀率結(jié)果:
對UIButton設(shè)置:
幀率結(jié)果:
兩種設(shè)置均是無離屏渲染
第四種方式:使用CAShapeLayer和UIBezierPath設(shè)置圓角
對UIImageview开仰、UIButton設(shè)置:
幀率結(jié)果:
兩種都是離屏渲染拟枚,掉幀更加嚴重薪铜≈诠基本上不能使用恩溅。
由上述測試可以知道,我上篇文章里所記筆記是有問題的谓娃。這里的測試結(jié)果可以看的徹底脚乡。
新方法:實際可采取利用
混合圖層
在需要裁剪的視圖上面添加一層視圖,以達到圓角的效果滨达。效果如下:
布局圖如下:
對于UIImageView
與UIButton
均可使用奶稠,且無離屏渲染
滾動的幀率:
代碼如下:
- (void)drawRoundedCornerImage {
UIImageView *iconImgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
iconImgV.image = [UIImage imageNamed:@"icon"];
[self.view addSubview:iconImgV];
[iconImgV mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(iconImgV.size);
make.top.equalTo(self.view.mas_top).offset(500);
make.centerX.equalTo(self.view);
}];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[self.view addSubview:imgView];
[imgView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(imgView.size);
make.top.equalTo(iconImgV.mas_top);
make.leading.equalTo(iconImgV.mas_leading);
}];
// 圓形
imgView.image = [self drawCircleRadius:100 outerSize:CGSizeMake(200, 200) fillColor:[UIColor whiteColor]];
}
// 繪制圓形
- (UIImage *)drawCircleRadius:(float)radius outerSize:(CGSize)outerSize fillColor:(UIColor *)fillColor {
UIGraphicsBeginImageContextWithOptions(outerSize, false, [UIScreen mainScreen].scale);
// 1、獲取當前上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//2.描述路徑
// ArcCenter:中心點 radius:半徑 startAngle起始角度 endAngle結(jié)束角度 clockwise:是否逆時針
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(outerSize.width * 0.5, outerSize.height * 0.5) radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:NO];
[bezierPath closePath];
// 3.外邊
[bezierPath moveToPoint:CGPointMake(0, 0)];
[bezierPath addLineToPoint:CGPointMake(outerSize.width, 0)];
[bezierPath addLineToPoint:CGPointMake(outerSize.width, outerSize.height)];
[bezierPath addLineToPoint:CGPointMake(0, outerSize.height)];
[bezierPath addLineToPoint:CGPointMake(0, 0)];
[bezierPath closePath];
//4.設(shè)置顏色
[fillColor setFill];
[bezierPath fill];
CGContextDrawPath(contextRef, kCGPathStroke);
UIImage *antiRoundedCornerImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return antiRoundedCornerImage;
}
此方法就是在要添加的視圖上在疊加一個部分透明的視圖捡遍,只對圓角部分進行遮擋锌订。圖層混合的透明度處理方式與mask正好相反。
此方法沒有離屏渲染画株,也可以自定義設(shè)置指定任意角為圓角辆飘。
總結(jié)
- 在可以使用混合圖層遮擋的場景下,優(yōu)先使用谓传。
- 通過.layer屬性設(shè)置蜈项,綜合性能上,還是有很大優(yōu)勢的续挟。