表視圖(UITableView)與表視圖控制器(UITableViewController)其實是一回事。 表視圖控制器是一種只能顯示表視圖的標准視圖控制器,可在表視圖占據整個視圖時使用這種控制器。雖然如此,相對於使用標准視圖控制器並自行添加表視圖,使用表視圖控制器除了將自動設置委托和數據源屬性外,沒有任何其它的優勢。
對於表視圖,最基本的設置是Content(內容)屬性,它包含兩個值:Static Cells和Dynamic Prototypes。Static Cells用來顯示固定的單元格,內容呈現主要通過Xcode的可視化編程來實現,不需要額外的代碼支持。Dynamic Prototypes為動態單元格,通過設定一個Cell模板,然后通過實現datasource接口和delegate接口的一些關鍵方法,從而動態生成表視圖。
需要注意的是,Static Cells模式僅僅適用於表視圖控制器(UITableViewController),當你嘗試設置標准視圖控制器下的表視圖(UITableView)content為Static Cells時,Xcode將提示一個錯誤:Static table views are only valid when embedded in UITableViewController instances。
表視圖有兩種外觀(Style):Plain和Grouped。下圖演示了這兩種樣式的差異:
Plain:
Grouped:
Separator屬性用於指定分區之間的分隔線外觀,它包含兩個下拉列表,一個用來設置分割線的外觀,有3個值:None(無分割線)、Single Line(單線條)、Single Line Etched(帶浮雕效果的線條);另一個用來設置線條的顏色。
Selection、Editing以及Show Selection on Touch復選框用於設置表格被用戶觸摸時的行為。
Index Row Limit屬性與UITableView的sectionIndexMinimumDisplayRowCount有關,這個屬性的含義是:"當行數達到某個數值,則顯示索引欄"。(索引欄是通過sectionIndexTitlesForTableView方法來實現的)。
每個單元格(Cell)都有獨特的標識符。這種標示符被稱為重用標識符(reuse identifier),用於在編碼時引用單元格;例如在Dynamic Prototypes模式下,可以指定多個Cell模板,為每個模板命名不同的標示符,然后根據情況調用不同的Cell模板。
單元格的Style屬性有下列五種:
Custom -- 用戶自定義
Basic -- 只包含一個Title
Right Detail --包含一個Title,並且在右側顯示Detail
Left Detail -- 包含一個Title,並且在左側顯示Detail
Subtitle -- 包含一個Title,並且在Title的下方顯示Detail
Basic、Right Detail和Subtitle有一個Image屬性,可以選擇任意一張圖片來添加圖像,這里只是用作占位。
下拉列表Selection用於設置單元格被選中時的顏色。只有三個值供選擇:None、Blue、Gray。
下拉列表Accessory用於設置單元格右邊的附屬圖形(通常是展開箭頭)。有四個值:None、Disclosure Indicator、Detail Disclosure、Checkmark。
Indentation設置欄包括Level和Width輸入框,分別對應indentationLevel(縮進等級)和indentationWidth(縮進寬度),最終的索引值=縮進等級*縮進寬度。縮進等級默認值為0(沒有縮進),縮進寬度默認值為10points。一般不直接設置縮進等級,而是根據行索引返回值:
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath { NSUInteger row = [indexPath row]; return row; }
Indent while editing復選框應該是“編輯狀態下縮進”(取消選擇,編輯狀態下可能就不縮進了,留待以后驗證)。
Shows Re-order Controls復選框應該是“顯示Re-order Controls",Re-order Controls是編輯狀態下出現的一系列控件。
要想讓表視圖正常工作,需要遵守兩個協議--UITableViewDataSource與UITableViewDelegate。
UITableViewDataSource(數據源協議)需要實現的主要方法:
numberOfSectionsInTableView: -- 返回表視圖的分區數。
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { //返回了2個分區 return 2; }
tableView:numberOfRowsInSection: -- 返回給定分區包含多少行。分區索引從0開始。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { //第一個分區返回2行,第二個分區返回5行 if(section==0) { return 3; } else if(section==1) { return 5; } return 0; }
tableView:titleForHeaderInSection: -- 返回一個字符串,用於給定分區的標題。
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { //第一個分區標題為"亞洲",第二個分區標題為"歐洲" if(section==0) { return @"亞洲"; } else { return @"歐洲"; } }
tableView:cellForRowAtIndexPath: -- 返回一個單元格對象,用於顯示在表視圖的指定位置。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"mycell"]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"mycell"]; if(indexPath.section==0)//第一個分區 { if(indexPath.row==0) { cell.textLabel.text = @"第一分區第一行"; cell.detailTextLabel.text = @"section1 row1"; cell.imageView.image = [UIImage imageNamed:@"s1r1.gif"]; } else { cell.textLabel.text = @"第一分區其它行"; cell.detailTextLabel.text = @"section1 rowX"; cell.imageView.image = [UIImage imageNamed:@"s1rx.gif"]; } } else//其它分區 { cell.textLabel.text = @"其它分區其它行"; cell.detailTextLabel.text = @"sectionX rowX"; cell.imageView.image = [UIImage imageNamed:@"sxrx.gif"]; } return cell; }
UITableViewDelegate(委托協議)主要響應用戶在表視圖進行的操作,最基礎的是用戶觸摸單元格:
tableView:didSelectRowAtIndexPath: 與 tableView:didDeselectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"you selected section %d row %d",indexPath.section,indexPath.row); }