什么樣的tableView是很優(yōu)異的?
- 滾動(dòng)時(shí),確保cell刷新幀率應(yīng)該在 50+/s !
- 展示cell時(shí),不能出現(xiàn)跳幀現(xiàn)象,導(dǎo)致?lián)Q面不流暢。
- 最關(guān)鍵的是在創(chuàng)建cell或者從緩存池取cell時(shí),讓系統(tǒng)花費(fèi)最少的時(shí)間,即盡可能的減少顯示cell的計(jì)算量。
1. 行高要緩存
舉個(gè)簡(jiǎn)單的栗子:如果現(xiàn)在要顯示100個(gè)Cell,當(dāng)前屏幕顯示5個(gè)。那么全局刷新UITableView時(shí), UITableView會(huì)先調(diào)用100次tableView:heightForRowAtIndexPath:
方法,然后調(diào)用5次 tableView:cellForRowAtIndexPath:
方法;滾動(dòng)屏幕時(shí),每當(dāng)Cell滾入屏幕,都會(huì)調(diào)用 一次tableView:heightForRowAtIndexPath:
和tableView:cellForRowAtIndexPath:
方 法。所以說(shuō)要提前計(jì)算并緩存好高度,因?yàn)?code>heightForRowAtIndexPath:是調(diào)用最頻繁的方法,如果是使用MVVM搭建框架,可以在viewModel中添加行高屬性,提前計(jì)算好行高。
如果是固定高度的cell,可以直接采用tableView.rowHeight = 88;
的方式,這樣寫,就需要實(shí)現(xiàn)tableView:heightForRowAtIndexPath:
方法了;如果實(shí)現(xiàn)這個(gè)方法,設(shè)置rowHeight
就會(huì)失效。
2.不要?jiǎng)討B(tài)創(chuàng)建子視圖
意思是:cell所有的子視圖都預(yù)先在初始化方法中創(chuàng)建,如果根據(jù)實(shí)際情況不需要顯示的可以設(shè)置 hidden.這樣能盡可能的減少cell創(chuàng)建或從緩存池取時(shí)因?yàn)椴季肿涌丶牡臅r(shí)間.
3. 渲染
為了保證TableView的流暢,當(dāng)快速滑動(dòng)的時(shí)候,cell必須被快速的渲染出來(lái)。所以cell渲染的速度必須快。如何提高cell的渲染速度呢?
(1)當(dāng)有圖像時(shí),預(yù)渲染圖像,在bitmap context先將其畫一遍,導(dǎo)出成UIImage對(duì)象,然后再繪制到屏幕,這會(huì)大大提高渲染速度。具體內(nèi)容可以自行查找“利用預(yù)渲染加速顯示iOS圖像”相關(guān)資料。
(2)渲染最好時(shí)的操作之一就是混合(blending)了,所以我們不要使用透明背景,將cell的opaque
值設(shè)為Yes,背景色不要使用clearColor,盡量不要使用陰影漸變等
(3)由于混合操作是使用GPU來(lái)執(zhí)行,我們可以用CPU來(lái)渲染,這樣混合操作就不再執(zhí)行??梢栽赨IView的drawRect方法中自定義繪制。
4.減少視圖的數(shù)目
當(dāng)cell上子視圖過多或者層級(jí)關(guān)系過于復(fù)雜的時(shí)候,cell的布局計(jì)算會(huì)大大增長(zhǎng),可能會(huì)導(dǎo)致一個(gè)runloop流程渲染不及時(shí),導(dǎo)致卡頓。
5.減少多余的繪制操作
在實(shí)現(xiàn)drawRect方法的時(shí)候,它的參數(shù)rect就是我們需要繪制的區(qū)域,在rect范圍之外的區(qū)域我們不需要進(jìn)行繪制,否則會(huì)消耗相當(dāng)大的資源。
6.異步化UI,不要阻塞主線程
使用Texture。可以保持復(fù)雜用戶界面的流暢和響應(yīng)。Texture的node是線程安全的,通過將圖像解碼、文本繪制和渲染等操作從主線程中遷移,從而保證主線程的響應(yīng)。
7. 不要給cell動(dòng)態(tài)添加subView
在初始化cell的時(shí)候就將所有需要展示的添加完畢,然后根據(jù)需要來(lái)設(shè)置hidden
屬性顯示和隱藏。
8. 懶加載圖片
快速滑動(dòng)的時(shí)候,不要加載圖片,滑動(dòng)停止時(shí),再加載圖片。這樣做可以防止在快速滑動(dòng)時(shí)加載圖片導(dǎo)致的卡頓問題。
9. 圓角優(yōu)化
圓角的不合理使用,會(huì)導(dǎo)致離屏渲染,觸發(fā)緩沖區(qū)的頻繁合并和上下文的的切換。所以需要合理的設(shè)置視圖的圓角,避免離屏渲染。
使用貝塞爾曲線UIBezierPath和Core Graphics框架畫出一個(gè)圓角
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image = [UIImage imageNamed:@"myImg"];
// 開始對(duì)imageView進(jìn)行畫圖
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
// 使用貝塞爾曲線畫出一個(gè)圓形圖
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.frame.size.width] addClip];
[imageView drawRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
// 結(jié)束畫圖
UIGraphicsEndImageContext();
[self.view addSubview:imageView];