UITableView簡單解析


原文:http://iiiyu.com/2013/04/15/learning-ios-notes-twenty/
UITableView是在iOS開發中,展示大量內容的首選。我個人認爲的原有有一下幾點:
1.UITableView的展現形式是爲移動設備專門設計過的。有較好的人機交互體驗。
2.從技術角度來說UITableView具有重用和延遲加載等特性。如果使用恰當。可以獲得一個App流暢的用戶體驗。
 
這樣,使得UITableView在iOS App中隨處可見。
 
原生應用
 
一些有名的App.圖片信息較老
 
包括遊戲
 
這些都說明UITableView在一個App中其實是一個很常用的控件。我應該好好的學習它。
 
關於數據的思考
沒有UITableView的時候我是這樣想的
首先思考爲什麼會有UITableView這樣的控件。我們做一個App的時候,就會有大量的數據需要顯示。比如weibo的每一個狀態。比如一個新聞App的很多條新聞。這些數據都會有一個特點就是他們的組織形式一樣,只是內容變化。有時候我們可能會根據一些條件進行分組。使得看來了是分組的。例如 聯繫人裏面會按照首字母來進行分組一樣。我們還可能會點擊數據以便查看更詳細的內容。
 
通過上面的簡單描述,如果來自己實現一個類似UITableView的結構。需要得到最核心的:
1.需要得到一共多少條數據
2.數據的具體內容是什麼
 
如果我們數據需要更加仔細的描述展示:
1.全部的數據一共有多少組
2.每一組有多少個數據
3.每一條數據的具體內容是什麼
 
UITableView是怎麼做的
在UITableView中。最重要的就是data source中的兩個方法。
  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 
  2.  
  3. - (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設置。再完成
  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 
  2.  
  3. - (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的重用是需要下面這樣的實現方法
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
  2.     static NSString *Cell = @"MyCell"
  3.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell]; 
  4.     if (!cell) { 
  5.         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Cell]; 
  6.     } 
  7.     return cell; 
重要的是UITableView的dequeueReusableCellWithIdentifier方法。
 
dequeueReusableCellWithIdentifier去一個隊列裏面需找有沒有相同ID的的Cell。如果有就提出來重用。可以重用的部分。如果沒有就跳進if裏面去創建。所以我們在if裏面創建的時候,不會改變的內容都可以在裏面創建,這樣就只用創建一次。需要改變的內容我們就放到if後面去寫。 這樣我們就能完成高效的UITableView。當然,理論上來說,你可以不用這樣的機制,而去直接每次創建一個Cell。不過這是非常浪費資源的一個做法,直接不提倡。
 
UITableView Delegate
當然,在寫UITableView肯定想控制的更多。才能完成設計師們辛辛苦苦畫出來的稿。這樣我們可以去看看Data source裏面剩下的函數和Delegate。當然就說一點
 
  1. //選中Cell響應事件 
  2. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
  3.     //選中後的反顯顏色即刻消失 
  4.     [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
 
這個是選中Cell時候會的出發點。如果要點擊以後做什麼事情 就在這裏做了。
 
找了篇目測還ok的中文blog可以先看看了解 
 
數據刷新
如果我們的modle更新了。相應的要體現到UITableView上面。簡單的我們可以reload整個TableView。這樣做很方便,而且數據上沒有問題。唯一的問題就是,reload整個TableView的效率太低了。而且,往往我們只是少數的Cell內容變化。所以沒有必要去reload整個TableView。而是那條數據變化去刷新對應的Cell就好了。這樣做效率提高很多。
 
具體涉及到的幾個函數
  1. - (void)beginUpdates; 
  2. - (void)endUpdates; 
  3.   
  4. - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; 
  5. - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; 
  6. - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation; 
  7.   
  8. - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation; 
  9. - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation; 
  10. - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; 
 
 
裏面寫了如何優化UITableView:
 
又找了一篇blog寫的很不錯的樣子,優化UITableView性能
 
後記
總結就是UITableView是一個高度設計的控件。它具有重用,分組,異步加載數據等方面需要我們注意。
 
其實這裏插進來寫UITableView是爲了寫NSFetchedResultsController。因爲NSFetchedResultsController就是爲UITableview量身打造的Core Data的類。
 
所以,先說明以下UITableView,然後再寫NSFetchedResultsController。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章