UITableView的數據源(dataSource)和代理(delegate)數組
UITableView須要一個數據源(dataSource)來顯示數據,UITableView會向數據源查詢一共有多少行數據以及每一行顯示什麼數據等。沒有設置數據源的UITableView只是個空殼。凡是遵照UITableViewDataSource協議的OC對象,均可以是UITableView的數據源。緩存
一般都要爲UITableView設置代理對象(delegate),以便在UITableView觸發一下事件時作出相應的處理,好比選中了某一行。凡是遵照了UITableViewDelegate協議的OC對象,均可以是UITableView的代理對象。通常會讓控制器充當UITableView的dataSource和delegate性能優化
UITableViewDataSourceide
@required佈局
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;性能
第section分區一共有多少行優化
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;動畫
建立第section分區第row行的UITableViewCell對象(indexPath包含了section和row)ui
@optionalatom
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
一共有多少個分區
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
第section分區的頭部標題
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
第section分區的底部標題
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
某一行是否能夠編輯(刪除)
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
某一行是否能夠移動來進行從新排序
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
UITableView右邊的索引欄的內容
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
選中了UITableView的某一行
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
某一行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
第section分區頭部的高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
第section分區尾部的高度
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
第section分區頭部顯示的視圖
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
第section分區尾部顯示的視圖
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
設置每一行的等級縮進(數字越小,等級越高)
UITableViewCell
UITableView的每一行都是一個UITableViewCell,經過dataSource的
tableView:cellForRowAtIndexPath:方法來初始化每一行
UITableViewCell是UIView的子類,內部有個默認的子視圖:contentView。contentView是UITableViewCell所顯示內容的父視圖,並負責顯示一些輔助指示視圖。輔助指示視圖的做用是顯示一個表示動做的圖標,能夠經過設置UITableViewCell的accessoryType來顯示,默認是UITableViewCellAccessoryNone(不顯示輔助指示視圖),其餘值以下:
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryCheckmark
UITableViewCell的contentView
contentView下默認有3個子視圖,其中的2個是UILabel(經過UITableViewCell的textLabel和detailTextLabel屬性訪問),第3個是UIImageView(經過UITableViewCell的imageView屬性訪問)
UITableViewCell還有一個UITableViewCellStyle屬性,用於決定使用contentView的哪些子視圖,以及這些子視圖在contentView中的位置
UITableViewCell對象的重用原理
iOS設備的內存有限,若是用UITableView顯示成千上萬條數據,就須要成千上萬個UITableViewCell對象的話,那將會耗盡iOS設備的內存。要解決該問題,須要重用UITableViewCell對象
重用原理:當滾動列表時,部分UITableViewCell會移出窗口,UITableView會將窗口外的UITableViewCell放入一個對象池中,等待重用。當UITableView要求dataSource返回UITableViewCell時,dataSource會先查看這個對象池,若是池中有未使用的UITableViewCell,dataSource會用新的數據配置這個UITableViewCell,而後返回給UITableView,從新顯示到窗口中,從而避免建立新對象
還有一個很是重要的問題:有時候須要自定義UITableViewCell(用一個子類繼承UITableViewCell),並且每一行用的不必定是同一種UITableViewCell(如短信聊天佈局),因此一個UITableView可能擁有不一樣類型的UITableViewCell,對象池中也會有不少不一樣類型的UITableViewCell,那麼UITableView在重用UITableViewCell時可能會獲得錯誤類型的UITableViewCell
解決方案:UITableViewCell有個NSString *reuseIdentifier屬性,能夠在初始化UITableViewCell的時候傳入一個特定的字符串標識來設置reuseIdentifier(通常用UITableViewCell的類名)。當UITableView要求dataSource返回UITableViewCell時,先經過一個字符串標識到對象池中查找對應類型的UITableViewCell對象,若是有,就重用,若是沒有,就傳入這個字符串標識來初始化一個UITableViewCell對象
重用UITableViewCell對象
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = @"UITableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:@"Text %i", indexPath.row];
return cell;
}
UITableViewCell的經常使用屬性
設置背景
backgroundView
設置被選中時的背景視圖
selectedBackgroundView
selectionStyle屬性可設置UITableViewCell被選中時的背景顏色:
UITableViewCellSelectionStyleNone 沒有顏色
UITableViewCellSelectionStyleBlue 藍色(默認)
UITableViewCellSelectionStyleGray 灰色
自定義UITableViewCell
通常有兩種方式:
用一個xib文件來描述UITableViewCell的內容
經過代碼往UITableViewCell的contentView中添加子視圖,在初始化方法(好比init、initWithStyle:reuseIdentifier:)中添加子控件,在layoutSubviews方法中分配子控件的位置和大小
UITableView的編輯模式
UITableView有個editing屬性,設置爲YES時,能夠進入編輯模式。在編輯模式下,能夠管理表格中的行,好比改變行的排列順序、增長行、刪除行,但不能修改行的內容
多種方式開啓編輯模式
@property(nonatomic,getter=isEditing) BOOL editing
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
刪除UITableView的行
首先要開啓編輯模式
實現UITableViewDataSource的以下方法:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// 若是UITableView提交的是刪除指令
if (editingStyle == UITableViewCellEditingStyleDelete) {
// 刪除真實數據
// [self.data removeObjectAtIndex:indexPath.row];
// 刪除UITableView中的某一行(帶動畫效果)
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
// 若是不考慮動畫效果,也能夠直接[tableView reload];
}
}
移動UITableView的行
首先要開啓編輯模式
實現UITableViewDataSource的以下方法(若是沒有實現此方法,將沒法換行)
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
int from = sourceIndexPath.row;
int to = destinationIndexPath.row;
if (from == to) return;
// 交換數據
// [self.data exchangeObjectAtIndex:from withObjectAtIndex:to];
}
選中UITableView的行
當某行被選中時會調用此方法(UITableViewDelegate的方法)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//取消選中某一行,讓被選中行的高亮顏色消失(帶動畫效果)
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
UITableView經常使用方法
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style
初始化一個UITableView,而且設置表格樣式
- (void)reloadData 從新訪問數據源,刷新界面
- (NSInteger)numberOfSections 分區的個數
- (NSInteger)numberOfRowsInSection:(NSInteger)section
第section分區的行數
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
經過indexPath找到對應的UITableViewCell對象
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
是否要開啓編輯模式
- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated
取消選中某一行,讓被選中行的高亮顏色消失(帶動畫效果)
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
經過identifier在(緩存)池中找到對應的UITableViewCell對象
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
移除indexPaths範圍內的全部行
@property(nonatomic,readonly) UITableViewStyle style 表格樣式
@property(nonatomic,assign) id <UITableViewDataSource> dataSource
數據源
@property(nonatomic,assign) id <UITableViewDelegate> delegate 代理
@property(nonatomic,getter=isEditing) BOOL editing 是否爲編輯模式
@property(nonatomic) UITableViewCellSeparatorStyle separatorStyle
設置分隔線的樣式
@property(nonatomic,retain) UIColor *separatorColor
設置分隔線的顏色
@property(nonatomic,retain) UIView *tableHeaderView
表頭顯示的視圖
@property(nonatomic,retain) UIView *tableFooterView
表尾顯示的視圖
@property(nonatomic) BOOL allowsSelection
是否容許選中行
@property(nonatomic) BOOL allowsSelectionDuringEditing
是否容許在編輯模式下選中行
@property(nonatomic) BOOL allowsMultipleSelection
是否容許選中多行
@property(nonatomic) BOOL allowsMultipleSelectionDuringEditing
是否容許在編輯模式下選中多行
UITableViewController
是UIViewController的子類,UITableViewController默認扮演了3種角色:視圖控制器、UITableView的數據源和代理
UITableViewController的view是個UITablView,由UITableViewController負責設置和顯示這個對象。UITableViewController對象被建立後,會將這個UITableView對象的dataSource和delegate指向UITableViewController本身
1、UITableView
1.數據展現的條件
1> UITableView的全部數據都是由數據源(dataSource)提供的,因此要想在UITableView展現數據,必須設置UITableView的dataSource數據源對象
2> 要想當UITableView的dataSource對象,必須遵照UITableViewDataSource協議,實現相應的數據源方法
3> 當UITableView想要展現數據的時候,就會給數據源發送消息(調用數據源方法),UITableView會根據方法返回值決定展現怎樣的數據
2.數據展現的過程
1> 先調用數據源的
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
得知一共有多少組
2> 而後調用數據源的
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
得知第section組一共有多少行
3> 而後調用數據源的
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
得知第indexPath.section組 第indexPath.row 行顯示怎樣的cell(顯示什麼內容)
3.常見數據源方法
1> 一共有多少組
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
2> 第section組一共有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
3> 第indexPath.section組 第indexPath.row行顯示怎樣的cell(顯示什麼內容)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
4> 第section組顯示怎樣的頭部標題
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
5> 第section組顯示怎樣的尾部標題
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
4.tableView刷新數據的方式
1> 修改模型數據
2> 刷新表格
* reloadData 總體刷新(每一行都會刷新)
* - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
局部刷新
5.性能優化
1> 定義一個循環利用標識
static NSString *ID = @"C1";
2> 從緩存池中取出可循環利用的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
3> 若是緩存池中沒有可循環利用的cell
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
4> 覆蓋cell上面的數據
cell.textLabel.text = [NSString stringWithFormat:@"第%d行數據", indexPath.row];
步驟一:建立UITableView。UITableView樣式爲組
步驟二:設置UITableView的數據源方法。
步驟三:實現UITableView的數據源方法,此方法會自動調用。
步驟四:用數組管理數據。
步驟五:每一個數組中都是一個字典,key:(header,footer,cityes).
工廠方法好處:簡化對象的實例化,快速建立對象。
UITableViewCellStyleDefault
UITableViewCellStyleValue1
UITableViewCellStyleSubtitle
UITableViewCellStyleValue2
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryCheckmark
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:@"哈哈哈哈哈" delegate:nil cancelButtonTitle:@"ABC" otherButtonTitles:@"123",@"456", nil];
// 彈出UIAlertView
[alert show];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:@"哈哈哈哈哈" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
// 彈出UIAlertView
[alert show];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
// 彈出UIAlertView
[alert show];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
// 彈出UIAlertView
[alert show];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"產品信息展現" message:p.name delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"肯定", nil];
alert.alertViewStyle = UIAlertViewStyleSecureTextInput;
// 彈出UIAlertView
[alert show];
步驟一:設置UIAlertView的代理
步驟二:遵照UIAlertView的協議
步驟三:實現UIAlertView的按鈕點擊協議方法。
步驟一: 取出文本框文字
注意UIAlertView中的文本框的角標是根據UIAlertView從上到下第幾個文本框決定的。最上面的文本框角標爲0.
步驟二: 修改模型數據
步驟三: 刷新表格
// 指定刷新indexPaths數組裏的行數。
注意indexPaths裏存儲的是NSIndexPath對象
UITableView默認只會加載出如今屏幕上面的cell,沒當有一個cell移除屏幕,就會存儲到緩存池裏找。
性能優化步驟:
步驟一:定義cell的標識(不須要每次都建立cell標識,所以須要使用static,static標識只會在第一次建立,之後都不會建立了。)
步驟二:從緩存池裏取cell
步驟三:判斷取出cell是否爲空,若是爲空就手動建立cell。