你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> UITableView(一)----基本介紹

UITableView(一)----基本介紹

編輯:IOS開發綜合

一、簡介

1. 繼承關系

UITableView繼承自UIScrollView,因此支持垂直滾動,而且性能極佳。UITableView的代理協議也繼承了UIScrollView的代理協議,可以通過實現UIScrollView的代理方法,監聽UITableView的變化。在UITableView中沒有列的概念,只有行的概念,數據都是按行顯示的。

2.使用場景

在iOS中,通常使用UITableView實現表格數據展示

3. 基本概念

Plain:單組樣式,整個UITableView只有一組數據
Grouped:多組樣式,整個UITableView有多組數據
dataSource:數據源,用於設置UITableView展示的數據
delegate:代理,用於監聽UITableView的操作和對UITableView的一些屬性進行設置
row:行,在每一行上展示數據,每一行對應一個cell
section:組,UITableView中可以把相似的內容分維一組
Header:頭部,一組的頭部
Footer:尾部,一組的尾部
estimatedHeight:估計高度,有估計行高、估計頭部高度、有估計尾部高度;給系統一個估算高度,系統會先創建一個cell,然後再調用設置行高的方法
Selection:選中
reload:刷新,創新裝載數據
緩沖池獲取cell:在緩存池中獲取帶有對應標記的cell

4. Cell的簡介

(1).UITableView的每一行都是一個UITableViewCell對象,通過dataSource的tableView:cellForRowAtIndexPath:方法來初始化每一行
(2).常見屬性

imageView:用於顯示圖片
textLabel:用於顯示大標題
detailTextLabel:用於顯示小標題
contentView:contentView是UITableViewCell所顯示內容的父視圖,可顯示一些輔助指示視圖,自定義cell的子控件都添加到contentView中
backgroundView:添加一個背景視圖,可以用於設置cell普通狀態下的背景顏色
selectedBackgroundView:選中一個cell之後的背景視圖,可用於設置選中時候的背景顏色
multipleSelectionBackgroundView:選中多個時候的背景視圖,可用於設置選中多個時候的背景顏色
reuseIdentifier:用於給cell設置一個標識,設置標識的cell用於性能優化
selectionStyle:選中時候的顯示類型
selected:設置是否選中
highlighted:是否在選中的時候呈現高亮

(3).常見方法

// 初始化一個cell和設置cell的標識
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier NS_AVAILABLE_IOS(3_0);

二、常見屬性

// UITableView類型,類型有單組和多組
@property (nonatomic, readonly) UITableViewStyle style;
// 數據源
@property (nonatomic, assign) id  dataSource;
// 代理
@property (nonatomic, assign) id  delegate;
// 行高
@property (nonatomic) CGFloat rowHeight;
// 組的頭部高度
@property (nonatomic) CGFloat sectionHeaderHeight; 
// 組的尾部高度
@property (nonatomic) CGFloat sectionFooterHeight;   
// 行的估計高度
@property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); 
// 組的頭部的估計高度
@property (nonatomic) CGFloat estimatedSectionHeaderHeight NS_AVAILABLE_IOS(7_0); 
// 組的尾部的估計高度
@property (nonatomic) CGFloat estimatedSectionFooterHeight 
// 設置背景視圖
@property(nonatomic, readwrite, retain) UIView *backgroundView NS_AVAILABLE_IOS(3_2);
// 設置頭部顯示的視圖
@property (nonatomic, retain) UIView *tableHeaderView;                           
// 設置尾部顯示的視圖
@property (nonatomic, retain) UIView *tableFooterView;
// 是否可以編輯
@property (nonatomic, getter=isEditing) BOOL editing;

三、常見方法

1. 關於TableView初始化

// 初始化一個tableView和設置tableView的樣式
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;

2. 關於TableView數據更新

// 所有數據全部更新
- (void)reloadData; 
// 更新索引
- (void)reloadSectionIndexTitles NS_AVAILABLE_IOS(3_0);

3.關於TableView的信息

// 獲取UITableView有多少組
- (NSInteger)numberOfSections;
// 獲取第section組有多少行
- (NSInteger)numberOfRowsInSection:(NSInteger)section;
// 獲取第section的位置和尺寸大小
- (CGRect)rectForSection:(NSInteger)section;
// 獲取第section的頭部的位置和尺寸大小
- (CGRect)rectForHeaderInSection:(NSInteger)section;
// 獲取第section的尾部的位置和尺寸大小
- (CGRect)rectForFooterInSection:(NSInteger)section;
// 獲取第indexPath.section組第indexPath.row行的位置和尺寸大小
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
// 獲取原點point所在的行的位置indexPath
- (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;
// 獲取指定的cell的位置indexPath
- (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell;
// 獲取rect范圍內的所有行的位置indexPath所組成的數組
- (NSArray *)indexPathsForRowsInRect:(CGRect)rect; 
// 獲取indexPath位置的cell
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
// 獲取看得見的所有的cell所組成的數組
- (NSArray *)visibleCells;
// 獲取看得見的所有的cell的位置indexPath所組成的數組
- (NSArray *)indexPathsForVisibleRows;
// 獲取第section組頭部的view
- (UITableViewHeaderFooterView *)headerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
// 獲取第section組尾部的view
- (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

4. 關於行或組的插入、刪除、更新

// 配合beginUpdates方法使用,在一個代碼塊中,提示開始更新,代碼塊中寫對行或組的插入、刪除
- (void)beginUpdates;
// 配合beginUpdates方法使用,在一個代碼塊中,提示結束更新,代碼塊中寫對行或組的插入、刪除
- (void)endUpdates;  
// 插入組數據
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
// 刪除組數據
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
// 更新組數據
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
// 移動組
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection NS_AVAILABLE_IOS(5_0);
// 插入行
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
// 刪除行
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
// 更新行
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
// 移動行
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);

5.關於選中的方法

// 獲取選中行的位置indexPath
- (NSIndexPath *)indexPathForSelectedRow; 
// 獲取選中多行的位置indexPath所組成的數組
- (NSArray *)indexPathsForSelectedRows NS_AVAILABLE_IOS(5_0);

6. 關於cell的重利用方法

// 重利用標識為identifier的cell,如果注冊過Cell,在沒有可用的cell時,會返回nil
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;
// 重利用標識為identifier的cell,如果你沒有注冊過cell,在沒有可用的cell時,程序直接崩潰
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
// 重利用標識為identifier的自定義的頭部或尾部
- (id)dequeueReusableHeaderFooterViewWithIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

7.關於cell的注冊方法

// 注冊xib創建的cell,設標識為identifier
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);
// 注冊cellClass創建的cell,設標識為identifier
- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
// 注冊xib創建的頭部或尾部,設標識為identifier
- (void)registerNib:(UINib *)nib forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
// 注冊aClass創建的頭部或尾部,設標識為identifier
- (void)registerClass:(Class)aClass forHeaderFooterViewReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);

四、數據源

要讓tableView顯示數據,要設置數據源,並實現必要的數據源方法

// 設置第section組的行數,必選
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// 設置位置為indexPath的cell,必選
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
// 設置tableView的組數,不實現該方法就默認只有一組
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
// 設置第section組的頭部
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection(NSInteger)section;
//  設置第section組的尾部
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// 設置位置為indexPath的是否可以編輯,與tableview:commitEditingStyle:方法配合使用
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// 當某一行可進行編輯時,實現該方法可以對那一行進行編輯
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// 設置位置為indexPath的是否可以移動, 與tableview:moveRowAtIndexPath方法配合使用
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
// 移動時使用
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
// 給組添加索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; 
// 設置每一組對應的索引,index表示組號,title表示索引標題
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index;

五、代理

tableView的代理可以實現scrollView的代理方法,因為協議繼承了scrollView代理協議

1.關於監聽顯示的方法

// 即將顯示位置為indexPath的cell時調用
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
// 即將顯示第section組的頭部時調用
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
// 即將顯示第section組的尾部時調用
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
// 位置為indexPath的cell不再在屏幕上顯示時調用
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath NS_AVAILABLE_IOS(6_0);
// 第section組的頭部不再在屏幕上顯示時調用
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);
// 第section組的尾部不再在屏幕上顯示時調用
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

2.關於設置高的方法

// 設置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
// 設置頭部的高
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
// 設置尾部的高
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

3.關於設置估計高的方法

// 估計行高
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);
// 估計頭部的高
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);
// 估計尾部的高
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section NS_AVAILABLE_IOS(7_0);

4.關於自定義頭部或尾部標題的view的方法

// 設置自定義View的頭部
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section; 
// 設置自定義view的尾部
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;

六、性能優化

1.問題

iOS設備的內存有限,如果用UITableView顯示成千上萬條數據,就需要成千上萬個UITableViewCell對象,那將會耗盡iOS設備的內存。要解決該問題,需要重用UITableViewCell對象

2.蘋果已經進行一次優化

優化:看到的cell才創建,看不見的cell就銷毀。
但其實蘋果沒有銷毀cell,只是把它放到了緩存池中

3.程序員的再次優化

思想:當要顯示新的cell時,如果緩存池中有類似的cell就直接拿過來重用
(1).重用原理
當滾動列表時,部分UITableViewCell會移出窗口,UITableView會將窗口外的UITableViewCell放入一個對象池中,等待重用。當UITableView要求dataSource返回UITableViewCell時,dataSource會先查看這個對象池,如果池中有未使用的UITableViewCell,dataSource會用新的數據配置這個UITableViewCell,然後返回給UITableView,重新顯示到窗口中,從而避免創建新對象。有時候需要自定義UITableViewCell(用一個子類繼承UITableViewCell),而且每一行用的不一定是同一種UITableViewCell,所以一個UITableView可能擁有不同類型的UITableViewCell,對象池中也會有很多不同類型的UITableViewCell,那麼UITableView在重用UITableViewCell時可能會得到錯誤類型的UITableViewCell
(2).解決方案
UITableViewCell有個NSString *reuseIdentifier屬性,可以在初始化UITableViewCell的時候傳入一個特定的字符串標識來設置reuseIdentifier(一般用UITableViewCell的類名)。當UITableView要求dataSource返回UITableViewCell時,先通過一個字符串標識到對象池中查找對應類型的UITableViewCell對象,如果有,就重用,如果沒有,就用傳入的這個字符串標識來初始化一個新的UITableViewCell對象

七、注意

1.同時設置cell的選中背景View和默認背景View,設置默認背景View優先級更高
2.在對cell進行編輯操作時,模型和cell的行數必須一致,不然會報錯
3.在storyboard中的tableView中添加cell,可以拖控件UITableViewCell,也可以在tableView的屬性欄設置Prototype Cells的個數
4.不設置tableView的數據源,即使實現了數據源協議的方法也不能顯示數據
5.不設置tableView的代理,即使實現了代理協議的方法也不能顯示數據
6.關於估計高度:只要返回了估計高度,那麼就會先調用tableView:cellForRowAtIndexPath:方法創建cell,再調用tableView:heightForRowAtIndexPath:方法獲取cell的真實高度
7.當控件的約束剛設置時,如果要緊接著使用控件的Frame,要先調用layoutIfNeeded方法進行強制布局,系統才對控件的Frame進行設置,否則Frame為0
8.設計自定義cell時,應該先把所有可能出現的控件布置好,哪些暫時不需要顯示的可以隱藏,在需要顯示時再取消隱藏
9.應該充分利用模型,因為模型始終貫穿tableView,可以用於記錄一些cell的不確定的屬性,如不等高時,用模型記錄每一個cell不同的高

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved