此子必成大器
此子必成大器
本文介紹內容主要是tableView的性能優化之不使用cornerRadius設置圖片圓角
有人問我為什么tableView滑動不流暢,甚至閃退,其實和cell中的圓角頭像使用了cornerRadius有關
優化點
- 行高一定要緩存
- 不要動態創建子視圖
- 所有子視圖都要預先創建
- 如果不需要顯示可以設置hidden
- 所有的子視圖都應該添加到
contentView
上 - 所有的子視圖都必須要指定顏色
- 不要動態的修改cornerRadius之類的圖層渲染相關屬性
- 使用顏色不要帶透明度,此處我們可以使用模擬器中的混合模式去檢測,如果如下圖所示出現紅色,除了UILabel之外,其他的我們都應該盡量去處理
- cell柵格化
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale; - 異步繪制
// 異步繪制
layer.drawsAsynchronously = YES;
Color Blended Layers模式下
下圖是使用了CornerRadius設置圓角之后Color Misaligned Images檢測效果
Color Misaligned Images模式下
此處使用了一張800*** 800的圖片設置在一個200*200的ImageView上,沒有做任何特殊處理
優化步驟
新建一個UIImage分類
-
定義方法
- (void)oa_cornerImageWithSize:(CGSize)size fillColor: (UIColor *)fillColor
completion:(void (^)(UIImage *))completion {dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSTimeInterval start = CACurrentMediaTime(); // 1. 利用繪圖,建立上下文 UIGraphicsBeginImageContextWithOptions(size, YES, 0); CGRect rect = CGRectMake(0, 0, size.width, size.height); // 2. 設置填充顏色 [fillColor setFill]; UIRectFill(rect); // 3. 利用 貝賽爾路徑 `裁切 效果 UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect]; [path addClip]; // 4. 繪制圖像 [self drawInRect:rect]; // 5. 取得結果 UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); // 6. 關閉上下文 UIGraphicsEndImageContext(); NSLog(@"%f", CACurrentMediaTime() - start); // 7. 完成回調 dispatch_async(dispatch_get_main_queue(), ^{ if (completion != nil) { completion(result); } }); }); }
3.控制器中代碼如下
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
iv.center = self.view.center;
[self.view addSubview:iv];
// 設置圖像
UIImage *image = [UIImage imageNamed:@"avatar.jpg"];
[image oa_cornerImageWithSize:iv.bounds.size fillColor:[UIColor whiteColor] completion:^(UIImage *image) {
iv.image = image;
}];
4.模擬器Color Blended Layers
和Color Misaligned Images
檢測結果如下圖
優化之后
5.Color Misaligned Images 如果是黃色說明圖像做過拉伸處理,如果在tableView快速滾動中,附加操作越多,性能越差
使用如上方法不僅可以裁切圓角頭像,同時解決了800**800設置在200200的ImageView上會拉伸的問題
此舉可以幫助tableView提升一部分性能