在項目中职辅,偶爾需要讓tableview里支持不同種類的cell,比如微博的原創(chuàng)微博和別人轉發(fā)的微博,就是兩種cell司蔬。又或是類似支付寶的的timeline也有各種類型的cell。在同一個tableview里實現(xiàn)不同種類的cell凭语,一般有兩種方法葱她,一種是把所有種類的cell先注冊了,再根據不同的identifer去加載cell似扔,一種是在init時創(chuàng)建不同的identifer的cell吨些。效果圖如下。
準備工作
創(chuàng)建一個基類的CDZBaseCell
炒辉,基類cell擁有一些共用的屬性和方法豪墅,如持有model,解析model黔寇。
創(chuàng)建不同的子類cell偶器,以兩個子類CDZTypeACell
CDZTypeBCell
為例,繼承自CDZBaseCell
缝裤,重寫一些方法屏轰,如高度,顯示視圖等等憋飞。
Datasource中準備好判斷index所在的cell種類的方法(如根據model的type屬性等)
- (Class)cellClassAtIndexPath:(NSIndexPath *)indexPath{
CDZTableviewItem *item = [self itemAtIndexPath:indexPath];
switch (item.type) {
case typeA:{
return [CDZTypeACell class];
}
break;
case typeB:{
return [CDZTypeBCell class];
}
break;
}
}
- (CDZTableviewItem *)itemAtIndexPath:(NSIndexPath *)indexPath{
return self.itemsArray[indexPath.row];
}
- (NSString *)cellIdentiferAtIndexPath:(NSIndexPath *)indexPath{
return NSStringFromClass([self cellClassAtIndexPath:indexPath]);
}
方法一:先注冊霎苗,根據identifer去加載不同的cell
先在tableview創(chuàng)建時注冊需要的不同種類,再判斷index對應的種類榛做,再根據identifer加載子類cell唁盏。
[self.tableview registerClass:[CDZTypeACell class] forCellReuseIdentifier:NSStringFromClass([CDZTypeBCell class])];
[self.tableView registerClass:[CDZTypeBCell class] forCellReuseIdentifier:NSStringFromClass([CDZTypeBCell class])];
并在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
中根據重用標識加載cell内狸。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CDZBaseCell *cell = [tableView dequeueReusableCellWithIdentifier:[self cellIdentiferAtIndexPath:indexPath] forIndexPath:indexPath];
cell.item = [self itemAtIndexPath:indexPath];
return cell;
}
方法二:在init時創(chuàng)建不同identifer的cell
在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
中判斷cell是否為nil,并根據index所在cell的種類初始化cell和其identifer厘擂。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CDZBaseCell *cell = [tableView dequeueReusableCellWithIdentifier:[self cellIdentiferAtIndexPath:indexPath]];
if (!cell) {
Class cls = [self cellClassAtIndexPath:indexPath];
cell = [[cls alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[self cellIdentiferAtIndexPath:indexPath]];
}
cell.item = [self itemAtIndexPath:indexPath];
return cell;
}
總結
個人更喜歡第二種昆淡,蘋果官方文檔也推薦第二種方法去重用cell。我覺得優(yōu)點是一個是在tableview劃分MVC架構時刽严,tableview創(chuàng)建時不需要知道cell的類型昂灵,而只需要知道datasouce,而datasource才是需要去分配cell類型的港庄。第二個是tableviewcell的初始化方法并非只能用initWithStyle(collectionview必須先注冊的原因則在于初始化方法只有initWithFrame)倔既。而使用了注冊,則是在復用池空時默認調用initWithStyle的方法鹏氧,如果需要用別的方法初始化就不可以了渤涌。第一種方法可以用在有一些庫需要先注冊后才能調用的,比如自動計算cell高度的庫FDTemplateLayoutCell
把还。
最后
所有源碼和Demo
如果您覺得有幫助,不妨給個star鼓勵一下,歡迎關注&交流
有任何問題歡迎評論私信或者提issue
QQ:757765420
Email:nemocdz@gmail.com
Github:Nemocdz
微博:@Nemocdz