1.創(chuàng)建UITableView
_exampleTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
創(chuàng)建UITableView對(duì)象,并設(shè)置代理和數(shù)數(shù)據(jù)源
_exampleTableView.delegate = self;
_exampleTableView.dataSource = self;
2.兩種樣式style
在創(chuàng)建UITableView的時(shí)候有兩種樣式,UITableViewStylePlain和UITableViewStyleGrouped
其中UITableViewStylePlain是默認(rèn)的樣式
區(qū)別:
1.有分區(qū)的時(shí)候
UITableViewStylePlain 區(qū)頭和區(qū)尾是懸浮的
UITableViewStyleGrouped 當(dāng)沒(méi)有設(shè)置分區(qū)頭時(shí)狐赡,會(huì)有默認(rèn)的分區(qū)頭的效果模她,區(qū)頭和區(qū)尾是隨cell一起滑動(dòng)的
2.無(wú)分區(qū)的時(shí)候
UITableViewStylePlain 單元格會(huì)鋪滿整個(gè)UITableView
<!--去除線-->
_exampleTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
3.注冊(cè)單元格
[_exampleTableView registerClass:[firstTableViewCell class] forCellReuseIdentifier:cellFirstID];
4.實(shí)現(xiàn)代理和數(shù)據(jù)源中協(xié)議的方法
#pragma mark - UITableViewDelegate
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
exampleModel *model = _arrayExample[indexPath.row];
return model.cellHeight;
}
#pragma mark - UITableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return _arrayExample.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
firstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellFirstID];
exampleModel *model = _arrayExample[indexPath.row];
[cell updateCellData:model];
return cell;
}
3.代理方法(執(zhí)行順序)
numberOfSectionsInTableView(分區(qū)個(gè)數(shù))
numberOfRowsInSection(每個(gè)分區(qū)有多少行)
heightForRowAtIndexPath(單元格高度)
cellForRowAtIndexPath(自定義單元格,當(dāng)cell要顯示的時(shí)候就會(huì)調(diào)用此方法)
先執(zhí)行numberOfSectionsInTableView是因?yàn)閁ITableView繼承于UIScrollview的
需要先設(shè)置UIScrollview的contentSize這個(gè)屬性,UITableView才可以顯示和滾動(dòng)起來(lái)
然后調(diào)用cellForRowAtIndexPath將返回的視圖添加到UIScrollview上.
4.UITableView的繪制
layoutSubviews
該方法是對(duì)子視圖的布局,在第一次設(shè)置數(shù)據(jù)源的時(shí)候調(diào)用
UITableView是繼承自UIScrollview,當(dāng)當(dāng)前視圖的 size 變化時(shí)才會(huì)觸發(fā)此方法(UITableView滑動(dòng)的時(shí)候是因?yàn)楦淖兞薱ell的高度所以才會(huì)導(dǎo)致layoutSubviews觸發(fā))
在布局前,要確定數(shù)據(jù)模型中已經(jīng)緩存了所有高度.
reloadData
數(shù)據(jù)發(fā)生變化,需要重新刷新cell顯示的內(nèi)容狈网,同時(shí)將所有顯示的UITableViewCell和未顯示可復(fù)用的UITableViewCell全部從父視圖移除然后重新創(chuàng)建
需要重新計(jì)算相關(guān)的高度值,并緩存起來(lái)
5.UITableViewCell復(fù)用機(jī)制
第一種方式:
(1)定義一個(gè)全局的變量
static NSString *cellFirstID = @"cellFirst";
(2)注冊(cè)cell
[_exampleTableView registerClass:[firstTableViewCell class] forCellReuseIdentifier:cellFirstID];
(3)在UITableViewDataSource的代理方法中獲取或創(chuàng)建cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//去緩存池中查找是否有這個(gè)標(biāo)識(shí)的cell 如果有那就取出來(lái)(取出來(lái)的前提是注冊(cè)了cell)
//如果沒(méi)有那就根據(jù)這個(gè)標(biāo)識(shí)去創(chuàng)建對(duì)應(yīng)的cell
firstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellFirstID];
exampleModel *model = _arrayExample[indexPath.row];
[cell updateCellData:model];
return cell;
}
第二種方式:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// 當(dāng)static關(guān)鍵字修飾局部變量時(shí),只會(huì)初始化一次,并且在程序中只有一份內(nèi)存
static NSString *cellFirstID = @"cell";
//去緩存池中查找是否有這個(gè)標(biāo)識(shí)的cell(根據(jù)標(biāo)識(shí)去取cell) 如果有就取出來(lái)
firstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellFirstID];
// 如果緩存池中沒(méi)有,則根據(jù)這個(gè)標(biāo)識(shí)去創(chuàng)建一個(gè)cell
if (cell==nil) {
cell = [[firstTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellFirstID];
}
exampleModel *model = _arrayExample[indexPath.row];
[cell updateCellData:model];
return cell;
}
總結(jié):
(1)iOS設(shè)備的內(nèi)存有限,不是每條數(shù)據(jù)都重新創(chuàng)建一個(gè)UITableViewCell,比如手機(jī)屏幕只能顯示7行單元格,那么就會(huì)創(chuàng)建含有Identifier標(biāo)識(shí)符的7個(gè)cell,這時(shí)候緩存池中是空的.
(2)當(dāng)向上滑動(dòng)的時(shí)候,上面的含有標(biāo)識(shí)符的cell已經(jīng)存放到緩存池中,當(dāng)顯示第8個(gè)單元格時(shí),就會(huì)去訪問(wèn)緩存池,查看是否有這個(gè)Identifier,如果有直接從緩存池中獲取.沒(méi)有的話則會(huì)根據(jù)這個(gè)標(biāo)識(shí)去創(chuàng)建一個(gè)cell.