1.引入
對于很多app,使用UITableView控件時都會對圖形進(jìn)行圓角處理,這樣顯得app美觀不少,常用的圓角處理,通過layer.cornerRadius和layer.maskToBounds設(shè)置即可。
// macOs 10.12, XCode 8 , iOS 10.0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell");
if cell == nil {
cell = UITableViewCell.init(style: .default, reuseIdentifier: "tableViewCell");
cell?.imageView?.layer.masksToBounds = true;
cell?.imageView?.layer.cornerRadius = RowHeight / 2;
cell?.imageView?.backgroundColor = UIColor.white;
cell?.backgroundColor = UIColor.white;
}
let cacheIndex = indexPath.row % 20;
let nameString = "siberian\(cacheIndex)";
let image = UIImage.init(named: nameString);
cell?.imageView?.image = image;
return cell!;
}
有離屏渲染,當(dāng)一頁圖片展示只有10張左右時,數(shù)量56FPS,看起來還是可以的,當(dāng)一頁設(shè)置有20張左右時,就只有45FPS了.
測試機(jī)為:iPhone 5s/iOS 8.3
iPhone 5s/iOS 8.3優(yōu)化前
測試機(jī):iPad Air 2/iOS 10.0
iPad Air 2/iOS 10.0優(yōu)化前
38~40FPS
2.優(yōu)化
1.離屏渲染處理
圓角是離屏渲染的一大殺手,所以必須處理好,采用Core Graphic在后臺進(jìn)行對圖片進(jìn)行clip處理,這樣就能很好的處理離屏渲染的問題。
// 繪制圓角圖片,沒有離屏渲染,但是有圖層混合。
DispatchQueue.global(qos: .background).async(execute: {
let rect = CGRect.init(x: 0, y: 0, width: RowHeight, height: RowHeight);
UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale);
let path = UIBezierPath.init(roundedRect: rect, cornerRadius: rect.height / 2.0);
path.addClip();
image?.draw(in: rect);
let lastImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.cache.setObject(_ :lastImage!, forKey: String(cacheIndex) as AnyObject, cost:Int((lastImage?.size.width)!) * Int((lastImage?.size.height)!) * Int(UIScreen.main.scale));
DispatchQueue.main.async(execute: {
cell.imageView?.image = lastImage;
});
});
2.緩存處理好的圖片
以上圖片是經(jīng)過處理后得到的,可以將其緩存,等到需要使用時,可以直接從本地緩存拉取。
let cacheImage = cache.object(forKey: String(cacheIndex) as AnyObject);
if let lastCacheImage = cacheImage {
cell.imageView?.image = lastCacheImage as? UIImage;
}
3.優(yōu)化圖片獲取的順序
當(dāng)用戶滑動界面時,調(diào)用順序為:
graph LR
scrollViewWillBeginDragging-->scrollViewDidScroll
scrollViewDidScroll-->scrollViewWillEndDragging
scrollViewWillEndDragging-->scrollViewDidEndDragging
scrollViewDidEndDragging-->scrollViewWillBeginDecelerating
scrollViewWillBeginDecelerating-->scrollViewDidScroll
scrollViewDidScroll-->scrollViewDidEndDecelerating
我們可以在滑動時,可以直接設(shè)置cell,但不去繪圖,只在停止時調(diào)用refreshTableView()
方法,方法如下:
// 當(dāng)滑動結(jié)束時調(diào)用
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
refreshTableView();
print(#function);
}
// 當(dāng)拖拽停止時調(diào)用
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
refreshTableView();
print(#function);
}
func refreshTableView() {
let arr:[IndexPath]? = self.tbView.indexPathsForVisibleRows;
if let visibleIndexArr = arr {
visibleIndexArr.forEach({ (indexPath) in
let cell = self.tbView.cellForRow(at: indexPath);
getImage(indexPath: indexPath, forCell: cell!);
});
}
}
4.優(yōu)化后的圖片
iPad air 2/iOS 10.0優(yōu)化后的離屏渲染
iPad air 2/iOS 10.0優(yōu)化后的圖層混合
iPad air 2/iOS 10.0優(yōu)化后的FPS
3.結(jié)語
通過上面后臺繪制圓角,緩存處理過的圖片,選擇適當(dāng)時機(jī)進(jìn)行圖片加載,使得幀率保持在56~58FPS左右。