在展示TableView前要配置好, 設(shè)置TableView的delegate和DataSource對(duì)象.
本章用到的代碼來(lái)之demo:UITableView Fundamentals for iOS和TheElements
創(chuàng)建TableView的基本知識(shí)
為創(chuàng)建TableView, 需要?jiǎng)?chuàng)建幾個(gè)相互交互的實(shí)體對(duì)象:視圖控制器, TableView自己和tableView的DataSource和delegate對(duì)象, 視圖控制器, DataSource和delegate通常是同一個(gè)對(duì)象. 視圖控制器的啟動(dòng)了調(diào)用序列, 圖3-1使用展示了這一過(guò)程.
- 視圖控制器使用frame和style來(lái)創(chuàng)建tableView實(shí)例. frame通常為screen的frame,減去各種bar(導(dǎo)航/狀態(tài)欄等)的高度即可. 在此刻也可設(shè)置一個(gè)全局變量表保存tableView, 或者用一個(gè)屬性保存tableView的全局屬性, 比如, 行高, autoresizing行為.
- 視圖控制器給tableView設(shè)置DataSource和delegate, 然后給TableView發(fā)送
reloadData
消息. - TableView會(huì)給DataSource發(fā)送
numberOfSectionsInTableView:
消息, DataSource會(huì)使用該方法返回TableView的section數(shù), 這個(gè)方法時(shí)可選的, 但如果你的tableView中有多個(gè)section的話, 必須實(shí)現(xiàn)該方法來(lái)告知TableView具有多個(gè)section. - 對(duì)于每一個(gè)section, DataSource都會(huì)收到TableView發(fā)送來(lái)的
TableView:numberOfRowsInSection:
消息, 該方法中返回每個(gè)section中的行數(shù) - 之后DataSource會(huì)收到對(duì)應(yīng)的可見(jiàn)cell的
tableView:cellForRowAtIndexPath:
消息, 然后返回對(duì)應(yīng)cell的UITableViewCell
對(duì)象, tableView使用該對(duì)象去繪制表視圖中的行.
圖4-1展示了DataSource中的required方法加上numberOfSectionsInTableView:
. DataSource和delegate除了實(shí)現(xiàn)required方法外, 可以實(shí)現(xiàn)其他optional方法來(lái)提供一些額外的特性, 比如實(shí)現(xiàn)tableView:titleForHeaderInSection:
方法來(lái)給section提供title. 你可以創(chuàng)建plain或者grouped樣式的tableView, 盡管以兩種樣式創(chuàng)建表視圖的過(guò)程是相同的, 但是您可能希望執(zhí)行不同類型的配置. 例如, 因?yàn)榉纸M表視圖通常呈現(xiàn)項(xiàng)目細(xì)節(jié), 所以您可能還希望添加自定義附件視圖(例如, 開(kāi)關(guān)和滑塊)或自定義內(nèi)容(例如, 文本字段). 具體見(jiàn)詳細(xì)地看看tableView中的cell
創(chuàng)建和配置TableView的一些建議
在APP中, tableView的用法很多, 想怎么用就怎么用, 你可以自定義一個(gè)對(duì)象去創(chuàng)建, 管理, 配置tableView, 但是你應(yīng)該使用UIKit提供的設(shè)計(jì)好的一些關(guān)于tableView的類和技術(shù), 也應(yīng)該遵循UIKit對(duì)于tableView使用的一些規(guī)范, 比如數(shù)據(jù)/表現(xiàn)分離, 下面是UIKit關(guān)于創(chuàng)建和使用tableView的一些建議:
- 盡量使用
UITableViewController
來(lái)創(chuàng)建和管理TableView - 如果你的APP中大量使用TableView的話, 那么你在創(chuàng)建xcode工程時(shí), 應(yīng)該使用Master-Detail應(yīng)用程序模板
- 對(duì)于展示連續(xù)的TableView, 你應(yīng)該使用自定義的
UITableViewController
, 這樣你既可以從storyboard中加載TableView, 也可以通過(guò)代碼創(chuàng)建一個(gè)關(guān)聯(lián)TableView.
如果你的界面是多個(gè)視圖組合而成, 而TableView只是組成界面的一部分, 那么你應(yīng)該使用UIViewController
來(lái)管理tableView, 不能用UITableViewController
, 因?yàn)楹笳邥?huì)使得tableView的size固定填充屏幕(減去各種bar的空間).
使用storyboard來(lái)創(chuàng)建TableView
使用xcode創(chuàng)建包含tableView的APP時(shí), 選則模板應(yīng)該包含方便創(chuàng)建TableView的代碼存根和storyboard, 該模板提供一個(gè)骨架, 你只需添加而外的代碼和設(shè)置即可, 這樣很方便
創(chuàng)建基于TableView的APP:
- 選擇Xcode, 選擇文件>新建>項(xiàng)目
- 在彈出的對(duì)話框的左側(cè),選擇iOS, 選擇應(yīng)用程序
- 在對(duì)話框的中間主要區(qū)域中, 選擇'Mater-Detail 應(yīng)用程序', 點(diǎn)擊'下一步'
- 選擇項(xiàng)目選項(xiàng)(確保使用storyboard), 然后點(diǎn)擊'下一步'
- 選擇項(xiàng)目的保存位置, 然后點(diǎn)擊'創(chuàng)建'
在第四步選擇設(shè)備時(shí), 會(huì)決定項(xiàng)目中的storyboard數(shù)量. 點(diǎn)擊項(xiàng)目導(dǎo)航欄中的storyboard文件, 會(huì)顯示storyboard編輯視圖. 如果你選擇的是iPhone, 那么storyboard中包含一個(gè)TableViewController, 如圖3-2所示.
確保畫(huà)布上的場(chǎng)景表示代碼中的主視圖控制器
- 在畫(huà)布上, 單擊場(chǎng)景標(biāo)題來(lái)選擇表視圖控制器
- 單擊工具欄區(qū)域頂部的
Identity button
來(lái)打開(kāi)Identity inspector - 檢查工程中的類是否包含UITableViewController的子類
選擇TableView的Display Style
TableView風(fēng)格包括兩種:plain和grouped
在storyboard中選擇TableView的style
- 點(diǎn)擊scene的中間來(lái)選中tableView.
- 在工具欄中選擇Attributes inspector
- 在tableView的Attributes inspector中選擇plain或者grouped style
選擇TableView的Content Type
在設(shè)計(jì)tableView的內(nèi)容是, storyboard中有兩種便捷的方式.
-
Dynamic prototypes 設(shè)計(jì)的cell的prototype的目的是為了復(fù)用. 如果你的cell復(fù)用時(shí), 使用的是相同的layout, 那么使用Dynamic, Dynamic的內(nèi)容由表視圖數(shù)據(jù)源(表視圖控制器)在運(yùn)行時(shí)以任意數(shù)量的單元格進(jìn)行管理埂蕊。圖3-3顯示了帶有一個(gè)Dynamic的plain表視圖模闲。
注意:如果storyboard中的tableView是dynamic, 那么tableView一定需要一個(gè)DataSource對(duì)象, 也就是說(shuō)
UITableViewController
的子類需要實(shí)現(xiàn)data source協(xié)議
- Static cells 使用是static cell的話, cell的內(nèi)容的layout, cell的個(gè)數(shù)已經(jīng)確定. TableView的cell和內(nèi)容在運(yùn)行前已經(jīng)確定好, 是固定的. 你還是設(shè)置section header等靜態(tài)信息. 當(dāng)TableView的cell的layout不會(huì)改變時(shí), 使用static cell. 如圖3-4, static cell的tableView.
注意:如果storyboard中的TableView使用static cell, 那么就不需要DataSource對(duì)象了, 因?yàn)門(mén)ableView的cell時(shí)確定的.
cell的重用標(biāo)識(shí)符(reuse identifier)是用來(lái)標(biāo)識(shí)重用的cell的, 標(biāo)識(shí)符的字符串最好是能夠描述cell中包含的內(nèi)容, 比如cell是用來(lái)展示鳥(niǎo)瞰圖的, 那么他的重用標(biāo)識(shí)符為@"BirdSightingCell"
設(shè)計(jì)TableView的cell
前面文章有講過(guò), UIKit為你提供了四種類型的cell. 如果系統(tǒng)提供的這四種類型不能滿足需求, 你可以繼承UITableViewCell
來(lái)自定義cell. 具體如何自定義cell你將在接下來(lái)的文章學(xué)到, 請(qǐng)關(guān)注本系列文章.
TableViewCell可以擁有附加視圖(Accessory view). 附加視圖是UIKit提供顯示在cell的右邊的一個(gè)視圖, 比如disclosure indicator, 使用>圖標(biāo)來(lái)表示, 告訴用戶點(diǎn)擊該圖標(biāo)可以獲取更多信息.
創(chuàng)建多個(gè)TableView
如果你的APP中存在和管理著多個(gè)TableView, 那么往storyboard中多拖幾個(gè)TableView, 可以通過(guò)將你創(chuàng)建的UITableViewController
子類和TableView綁定.
往工程中添加自定義類文件
- 打開(kāi)Xcode, 選擇File > New > File
- 在彈出的對(duì)話框中選擇iOS中的cocoa touch
- 在對(duì)話框中選擇Object-C類, 點(diǎn)擊下一步
- 輸入文件名稱, 選擇
UITableViewController
, 點(diǎn)擊下一步 - 選擇保存的路徑, 點(diǎn)擊創(chuàng)建
往storyboard中添加表視圖控制器
- 打開(kāi)要添加TableView的storyboard
- 在對(duì)象庫(kù)中拖一個(gè)TableViewController到storyboard中
- 選中添加的scene, 點(diǎn)擊utility area中的Identity button
- 在custom class組中, 選擇剛創(chuàng)建的類
- 選擇TableView的cell的style(dynamic/static)
- 往新的scene上添加一個(gè)segue
通過(guò)創(chuàng)建一個(gè)demo APP可以學(xué)到更多
通過(guò)Apple實(shí)戰(zhàn)指導(dǎo)Your Second iOS App: Storyboards, 你可以學(xué)習(xí)如何通過(guò)storyboard技術(shù)來(lái)創(chuàng)建APP, 在該指導(dǎo)文檔中, 你將會(huì)學(xué)習(xí)如何創(chuàng)建一個(gè)基于導(dǎo)航的APP, 以及如何創(chuàng)建使用TableView來(lái)構(gòu)建界面.
使用代碼創(chuàng)建tableView
使用UITableViewController
的好處, 能夠省寫(xiě)很多代碼, 而且可以避免一些錯(cuò)誤.
實(shí)現(xiàn)DataSource和Delegate協(xié)議
使一個(gè)類成為T(mén)ableView的DataSource和delegate需要遵守UITableViewDatasSource
和UITableViewDelegate
協(xié)議. 代碼清單3-1展示TableView的DataSource和Delegate.
代碼清單3-1 遵守DataSource和delegate協(xié)議
@interface RootViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) NSArray *timeZoneNames;
@end
創(chuàng)建和配置tableView
第二步是alloc, init出TableView實(shí)例. 代碼清單3-2展示了創(chuàng)建一個(gè)plain表視圖, 然后設(shè)置各種屬性,frame, DataSource, delegate等信息, 在使用UITableViewController
時(shí), 是不用設(shè)置這些屬性的, 因?yàn)樗詣?dòng)幫你設(shè)置好了
代碼清單3-2 創(chuàng)建一個(gè)tableView
- (void)loadView
{
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
tableView.delegate = self;
tableView.dataSource = self;
[tableView reloadData];
self.view = tableView;
}
使用數(shù)據(jù)動(dòng)態(tài)填充tableView
當(dāng)TableView被創(chuàng)建后, TableView會(huì)收到reloadData
消息, 讓TableView去訪問(wèn)DataSource和delegate對(duì)象, 來(lái)獲取section, row等信息, 這時(shí)DataSource會(huì)告訴TableView該顯示多少section和row. 之后DataSource重復(fù)調(diào)用tableView:cellForRowAtIndexPath:
方法,返回一個(gè)UITableViewCell
對(duì)象, 來(lái)告訴tableView該如何繪制row.(當(dāng)你滾動(dòng)tableView時(shí), 也會(huì)導(dǎo)致tableView:cellForRowAtIndexPath:
被調(diào)用, 這是因?yàn)樾耤ell會(huì)顯示).
前面提過(guò), 如果tableView是動(dòng)態(tài)的(dynamic), 那么就必須實(shí)現(xiàn)DataSource協(xié)議, 代碼清單3-3展示一個(gè)實(shí)現(xiàn)了DataSource和delegate協(xié)議的類.
代碼清單3-3 給動(dòng)態(tài)tableView填充數(shù)據(jù)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [regions count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Number of rows is the number of time zones in the region for the specified section.
Region *region = [regions objectAtIndex:section];
return [region.timeZoneWrappers count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
// The header for the section is the region name -- get this from the region at the section index.
Region *region = [regions objectAtIndex:section];
return [region name];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"MyReuseIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
Region *region = [regions objectAtIndex:indexPath.section];
TimeZoneWrapper *timeZoneWrapper = [region.timeZoneWrappers objectAtIndex:indexPath.row];
cell.textLabel.text = timeZoneWrapper.localeName;
return cell;
}
在tableView:cellForRowAtIndexPath:
方法中, 出于性能考慮, DataSource會(huì)盡可能的復(fù)用cell, 首先會(huì)發(fā)送一個(gè)dequeueReusableCellWithIdentifier:
消息給到tableView, 要求TableView提供一個(gè)特定重用標(biāo)識(shí)符的復(fù)用cell, 如果該cell不存在, DataSource要負(fù)責(zé)創(chuàng)建該cell, 并設(shè)置特定的reuse identifier. DataSource還要負(fù)責(zé)設(shè)置cell的content(上例中, 設(shè)置text)然后返回cell給TableView. 具體如何設(shè)置cell的content請(qǐng)看后續(xù)文章詳細(xì)地看看tableView中的cell
如果你的cell是在storyboard定義的, 使用dequeueReusableCellWithIdentifier:
方法進(jìn)行獲取cell時(shí)總是有效的, 如果那里不需要使用復(fù)用的cell, 那么該方法會(huì)返回一個(gè)使用storyboard信息創(chuàng)建的新cell. 這樣就不需要檢查返回值是否為nil了.
使用數(shù)據(jù)動(dòng)態(tài)填充tableView
如果TableView是靜態(tài)的, 那么就不需要DataSource對(duì)象了, TableView在編譯期配置了好, 不需要在運(yùn)行期在去調(diào)用DataSource的方法了. 但是你需要使用data model中的數(shù)據(jù)來(lái)填充TableView的內(nèi)容, 下面代碼清單3-4就是一個(gè)這樣的示例.(改代碼示例來(lái)源Your Second iOS App: Storyboards)
代碼清單3-4 使用數(shù)據(jù)填充靜態(tài)tableView
- (void)viewDidLoad
{
[super viewDidLoad];
BirdSighting *theSighting = self.sighting;
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
}
if (theSighting) {
self.birdNameLabel.text = theSighting.name;
self.locationLabel.text = theSighting.location;
self.dateLabel.text = [formatter stringFromDate:(NSDate*)theSighting.date];
}
}
上面的代碼實(shí)例中, 在viewDidLoad
(該方法會(huì)等view加載到內(nèi)存后調(diào)用)對(duì)tableView進(jìn)行填充數(shù)據(jù), 其中一些屬性(birdNameLabel,locationLabel)是storyboard中的outlet.
填充索引列表
當(dāng)需要大量按字母分類排序的數(shù)據(jù)時(shí), 可以使用索引列表(如第一章圖1-2所示). 索引列表是一種plain風(fēng)格的TableView, 而且還需要對(duì)DataSource對(duì)象進(jìn)行一些特殊的設(shè)置:
sectionIndexTitlesForTableView:
返回一組字符串作為index使用tableView:titleForHeaderInSection:
為每一個(gè)section指定一個(gè)index, 作為section的titletableView:sectionForSectionIndexTitle:atIndex:
指定用戶點(diǎn)擊進(jìn)入相應(yīng)的section的index.
在構(gòu)建索引列表時(shí), 用來(lái)填充tableView的數(shù)據(jù)結(jié)構(gòu)與索引結(jié)構(gòu)相符. 一般需要?jiǎng)?chuàng)建一個(gè)二維數(shù)組來(lái)保存數(shù)據(jù). section的個(gè)數(shù)通過(guò)外層數(shù)組來(lái)反映, 內(nèi)層數(shù)組代表一個(gè)section中的內(nèi)容, 而且還要對(duì)這些數(shù)組按照現(xiàn)行索引順序進(jìn)行排序(一般按照字面表排序, 如A-Z). 可以通過(guò)類UILocalizedIndexedCollation(該類可以根據(jù)特定localization)來(lái)對(duì)二維數(shù)組排序, 這樣可以簡(jiǎn)化構(gòu)建順序的二維數(shù)據(jù)這種數(shù)據(jù)結(jié)構(gòu).
模型對(duì)象需要提供一個(gè)string屬性和返回string的方法來(lái)供類UILocalizedIndexedCollation
進(jìn)行檢驗(yàn). 如果模型對(duì)象提供的是一個(gè)方法, 那么這個(gè)方法應(yīng)該不需要參數(shù). 如果一個(gè)model對(duì)象可以代表tableView中的行, 這樣非常方便, 所以在定義model時(shí), 你可以定義一個(gè)屬性來(lái)保存section的index, 或者row的index. 代碼清單4-5展示了這樣的model的定義
代碼清單3-5 設(shè)計(jì)model類
@interface State : NSObject
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *capitol;
@property(nonatomic,copy) NSString *population;
@property NSInteger sectionNumber;
@end
在填充tableView數(shù)據(jù)之前, 你應(yīng)該將數(shù)據(jù)創(chuàng)建加載好. 下面代碼展示了數(shù)據(jù)的加載和數(shù)據(jù)的排序處理
代碼清單3-6 loading數(shù)據(jù)
- (void)viewDidLoad {
[super viewDidLoad];
UILocalizedIndexedCollation *theCollation = [UILocalizedIndexedCollation currentCollation];
self.states = [NSMutableArray arrayWithCapacity:1];
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];
NSArray *tempArray;
NSMutableArray *statesTemp;
if (thePath && (tempArray = [NSArray arrayWithContentsOfFile:thePath]) ) {
statesTemp = [NSMutableArray arrayWithCapacity:1];
for (NSDictionary *stateDict in tempArray) {
State *aState = [[State alloc] init];
aState.name = [stateDict objectForKey:@"Name"];
aState.population = [stateDict objectForKey:@"Population"];
aState.capitol = [stateDict objectForKey:@"Capitol"];
[statesTemp addObject:aState];
}
} else {
return;
}
當(dāng)數(shù)據(jù)加載完后, 可以使用UILocalizedIndexedCollation
類對(duì)數(shù)據(jù)進(jìn)行處理
代碼清單3-7 對(duì)數(shù)據(jù)進(jìn)行索引化
// viewDidLoad continued...
// (1)
for (State *theState in statesTemp) {
NSInteger sect = [theCollation sectionForObject:theState collationStringSelector:@selector(name)];
theState.sectionNumber = sect;
}
// (2)
NSInteger highSection = [[theCollation sectionTitles] count];
NSMutableArray *sectionArrays = [NSMutableArray arrayWithCapacity:highSection];
for (int i = 0; i < highSection; i++) {
NSMutableArray *sectionArray = [NSMutableArray arrayWithCapacity:1];
[sectionArrays addObject:sectionArray];
}
// (3)
for (State *theState in statesTemp) {
[(NSMutableArray *)[sectionArrays objectAtIndex:theState.sectionNumber] addObject:theState];
}
// (4)
for (NSMutableArray *sectionArray in sectionArrays) {
NSArray *sortedSection = [theCollation sortedArrayFromArray:sectionArray
collationStringSelector:@selector(name)];
[self.states addObject:sortedSection];
}
} // end of viewDidLoad
對(duì)上面代碼做一些說(shuō)明:
- 遍歷所有model數(shù)據(jù), 調(diào)用collation對(duì)象的
sectionForObject:collationStringSelector:
方法, 該方法的參數(shù)是一個(gè)model對(duì)象, 和一個(gè)model對(duì)象屬性或者定義的方法(用來(lái)進(jìn)行檢驗(yàn)的), 然后該方法會(huì)返回一個(gè)處于哪個(gè)section的index. 將前面的index設(shè)置為model的sectionNumber
- 創(chuàng)建一個(gè)section數(shù)組(外層), 保存每一個(gè)section中的數(shù)據(jù).
- 循環(huán)遍歷一個(gè)模型數(shù)組中的每個(gè)數(shù)據(jù), 將其加入相應(yīng)的section數(shù)組(內(nèi)存)中.
- 然后調(diào)用collation manager的
sortedArrayFromArray:collationStringSelector:
方法來(lái)對(duì)section數(shù)組(外層)中的內(nèi)層數(shù)組排序
經(jīng)過(guò)上面的步驟后, DataSource已經(jīng)將數(shù)據(jù)準(zhǔn)備好, 下面是具體設(shè)置列表的index, 代碼清單3-8展示了這一過(guò)程, 該過(guò)程調(diào)用了UILocalizedIndexedCollation
類的兩個(gè)方法sectionIndexTitles
和sectionForSectionIndexTitleAtIndex:
來(lái)完成任務(wù), 注意在方法tableView:titleForHeaderInSection:
方法中, 會(huì)將空的section從列表中移除.
代碼清單3-8 為tableView提供section-index數(shù)據(jù)
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([[self.states objectAtIndex:section] count] > 0) {
return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
}
return nil;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
最后實(shí)現(xiàn)DataSource協(xié)議方法, 如代碼清單3-9所示
代碼清單3-9 填充索引列表中的行
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.states count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.states objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"StateCell";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
State *stateObj = [[self.states objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.textLabel.text = stateObj.name;
return cell;
}
如果你的TableView是索引列表, 那么請(qǐng)注意, 你應(yīng)該將cell的accessoryType
設(shè)置為UITableViewCellAccessoryNone
.
經(jīng)過(guò)上面的一個(gè)步驟輪廓, 你可以調(diào)用reloadSectionIndextitles
方法來(lái)reload列表的index
tableView的可選性配置
對(duì)于tableView, UIKit提供了很多Api來(lái)對(duì)tableView進(jìn)行配置, 可以在外觀和行為上對(duì)tableView進(jìn)行各種控制, 比如控制section, 控制row等等. 下面就這些配置提供幾個(gè)方向給你選擇.
添加一個(gè)自定義標(biāo)題
在對(duì)tableView進(jìn)行配置時(shí), 使用UITableView
類的方法對(duì)tableView配置是全局性的. 下面代碼展示了如何為tableView添加一個(gè)自定義的title(使用UILabel
)
代碼清單3-10 為tableView添加一個(gè)標(biāo)題
- (void)loadView {
CGRect titleRect = CGRectMake(0, 0, 300, 40);
UILabel *tableTitle = [[UILabel alloc] initWithFrame:titleRect];
tableTitle.textColor = [UIColor blueColor];
tableTitle.backgroundColor = [self.tableView backgroundColor];
tableTitle.opaque = YES;
tableTitle.font = [UIFont boldSystemFontOfSize:18];
tableTitle.text = [curTrail objectForKey:@"Name"];
self.tableView.tableHeaderView = tableTitle;
[self.tableView reloadData];
}
提供一個(gè)section表示
代碼清單3-11 返回section的title
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
// Returns section title based on physical state: [solid, liquid, gas, artificial]
return [[[PeriodicElements sharedPeriodicElements] elementPhysicalStatesArray] objectAtIndex:section];
}
縮進(jìn)一行
代碼清單3-12 設(shè)置行的縮進(jìn)
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
if ( indexPath.section==TRAIL_MAP_SECTION && indexPath.row==0 ) {
return 2;
}
return 1;
}
改變一行的高度
代碼清單3-13 控制不同行的行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat result;
switch ([indexPath row])
{
case 0:
{
result = kUIRowHeight;
break;
}
case 1:
{
result = kUIRowLabelHeight;
break;
}
}
return result;
}
自定義Cell
關(guān)于要自定義cell, 那么主要的操作集中在DataSource的tableView:cellForRowAtIndexPath:
方法中, 返回一個(gè)自定義的UITableViewCell
子類的cell, 具體內(nèi)容請(qǐng)看下篇文章詳細(xì)地看看tableView中的cell