轉自蕭宸宇的博客 php
UITableView是在iOS開發中,展現大量內容的首選。我我的認爲的緣由有如下幾點:html
1.UITableView的展示形式是爲移動設備專門設計過的。有較好的人機交互體驗。ios
2.從技術角度來講UITableView具備重用和延遲加載等特性。若是使用恰當。能夠得到一個App流暢的用戶體驗。網絡
這樣,使得UITableView在iOS App中隨處可見。app
原生應用異步
一些有名的App.圖片信息較老函數
包括遊戲性能
這些都說明UITableView在一個App中實際上是一個很經常使用的控件。我應該好好的學習它。學習
關於數據的思考 優化
沒有UITableView的時候我是這樣想的
首先思考爲何會有UITableView這樣的控件。咱們作一個App的時候,就會有大量的數據須要顯示。好比weibo的每個狀態。好比一個新聞App的不少條新聞。這些數據都會有一個特色就是他們的組織形式同樣,只是內容變化。有時候咱們可能會根據一些條件進行分組。使得看來了是分組的。例如 聯繫人裏面會按照首字母來進行分組同樣。咱們還可能會點擊數據以便查看更詳細的內容。
經過上面的簡單描述,若是來本身實現一個相似UITableView的結構。須要獲得最核心的:
1.須要獲得一共多少條數據
2.數據的具體內容是什麼
若是咱們數據須要更加仔細的描述展現:
1.所有的數據一共有多少組
2.每一組有多少個數據
3.每一條數據的具體內容是什麼
UITableView是怎麼作的
在UITableView中。最重要的就是data source中的兩個方法。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
什麼是data source。字面意思就是很明白,數據的來源。通常狀況下咱們會設置擁有UITableView的這個UIViewController爲他的data source。由於根據MVC來講。
UITableView是View,UIViewController是Controller。View須要的數據,應該是Controller去跟Model協調而後得到,之後由Controller去給View來進行顯示。View永遠的不去直接跟Model聯繫。這樣當UITableView初始化的時候。他就會去問他的data source。我須要顯示多少行數據啊。每一行的數據都是什麼內容啊。這時候UIViewController應該已經從Model拿到了數據。而後經過- (NSInteger)tableView:(UITableView )tableView numberOfRowsInSection:(NSInteger)section;告訴UITableview,恩你的這一組要顯示n條數據。又用- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath )indexPath函數告訴UITableView說,第幾組第幾條數據的具體內容是什麼。
UITableView還有一個比較犀利的地方就是若是你的數據有10000條。它確定不是把10000條都加載進來。而是隻加載須要顯示的條目數據。這樣設計,使得UITableView的流暢程度大大提升。值得注意的是,若是Cell裏面的數據是從網絡 or Core Data等其餘地方讀取的。咱們應該把讀取動做寫成異步的。不阻塞主線程。取到數據之後在回答主線程去刷新UI。
UITableView從建立到顯示的調用順序以下圖
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView這個函數是最早調用,可是它默認返回1.因此並非必須的。若是你的UITableView分了好幾組,這個就是用來返回組的數量的。
這樣完成了設置UITableView的data source設置。再完成
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
這兩個函數。咱們就能夠獲得一個能顯示的UITableView了。
如今是是僅僅解釋了UITableView的數據是怎麼來的,而後怎麼對應到UITableView上面。
UITableViewCell
UITableViewCell具體的每一條數據展現的具體View。首先在UITableView裏面有這樣一個特色,每個Cell的大概樣子都長的差很少,只是裏面具體的內容稍有變化。這樣在UI裏面咱們應該是重用相同的部分,改變不一樣的部分。這樣才能提升效率。由於在UiTableView這個視圖裏面,用戶習慣性快速的滾動,視圖和數據內容都會快速的變化,若是效率問題處理很差,很容易有卡頓的現象。形成用戶體驗的下降。
若是使用默認的UITableViewCell風格,有如下四種:
UITableViewCellStyleDefault
UITableViewCellStyleSubtile
UITableViewCellStyleValue1
UITableViewCellStyleValue2
固然若是是須要自定義Cell也是很簡單。 用xib拖一個,徹底能夠GUI的方式來建立,非常方便。
(Google一個栗子吧,寫不動了)插一句,Cell的重用是須要下面這樣的實現方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *Cell = @"MyCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Cell]; } return cell; }
重要的是UITableView的dequeueReusableCellWithIdentifier方法。
dequeueReusableCellWithIdentifier去一個隊列裏面需找有沒有相同ID的的Cell。若是有就提出來重用。能夠重用的部分。若是沒有就跳進if裏面去建立。因此咱們在if裏面建立的時候,不會改變的內容均可以在裏面建立,這樣就只用建立一次。須要改變的內容咱們就放到if後面去寫。 這樣咱們就能完成高效的UITableView。固然,理論上來講,你能夠不用這樣的機制,而去直接每次建立一個Cell。不過這是很是浪費資源的一個作法,直接不提倡。
UITableView Delegate
固然,在寫UITableView確定想控制的更多。才能完成設計師們辛辛苦苦畫出來的稿。這樣咱們能夠去看看Data source裏面剩下的函數和Delegate。固然就說一點
//選中Cell響應事件 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //選中後的反顯顏色即刻消失 [tableView deselectRowAtIndexPath:indexPath animated:YES]; }
這個是選中Cell時候會的出發點。若是要點擊之後作什麼事情 就在這裏作了。
找了篇目測還ok的 中文blog能夠先看看了解
數據刷新
若是咱們的modle更新了。相應的要體現到UITableView上面。簡單的咱們能夠reload整個TableView。這樣作很方便,並且數據上沒有問題。惟一的問題就是,reload整個TableView的效率過低了。並且,每每咱們只是少數的Cell內容變化。因此沒有必要去reload整個TableView。而是那條數據變化去刷新對應的Cell就行了。這樣作效率提升不少。
具體涉及到的幾個函數
- (void)beginUpdates; - (void)endUpdates; - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation; - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation; - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
裏面寫了如何優化UITableView:
又找了一篇blog寫的很不錯的樣子, 優化UITableView性能
後記
總結就是UITableView是一個高度設計的控件。它具備重用,分組,異步加載數據等方面須要咱們注意。
其實這裏插進來寫UITableView是爲了寫NSFetchedResultsController。由於NSFetchedResultsController就是爲UITableview量身打造的Core Data的類。
因此,先說明如下UITableView,而後再寫NSFetchedResultsController。