iOS中tableview支持不同種類的cell

在項目中,偶爾需要讓tableview里支持不同種類的cell,比如微博的原創微博和別人轉發的微博,就是兩種cell。又或是類似支付寶的的timeline也有各種類型的cell。在同一個tableview里實現不同種類的cell,一般有兩種方法,一種是把所有種類的cell先注冊了,再根據不同的identifer去加載cell,一種是在init時創建不同的identifer的cell。效果圖如下。


屏幕快照 2017-01-08 03.43.03.png

準備工作

創建一個基類的CDZBaseCell,基類cell擁有一些共用的屬性和方法,如持有model,解析model。

創建不同的子類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創建時注冊需要的不同種類,再判斷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時創建不同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。我覺得優點是一個是在tableview劃分MVC架構時,tableview創建時不需要知道cell的類型,而只需要知道datasouce,而datasource才是需要去分配cell類型的。第二個是tableviewcell的初始化方法并非只能用initWithStyle(collectionview必須先注冊的原因則在于初始化方法只有initWithFrame)。而使用了注冊,則是在復用池空時默認調用initWithStyle的方法,如果需要用別的方法初始化就不可以了。第一種方法可以用在有一些庫需要先注冊后才能調用的,比如自動計算cell高度的庫FDTemplateLayoutCell

最后

所有源碼和Demo

如果您覺得有幫助,不妨給個star鼓勵一下,歡迎關注&交流

有任何問題歡迎評論私信或者提issue

QQ:757765420
Email:nemocdz@gmail.com
Github:Nemocdz
微博:@Nemocdz

謝謝觀看

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 概述在iOS開發中UITableView可以說是使用最廣泛的控件,我們平時使用的軟件中到處都可以看到它的影子,類似...
    liudhkk閱讀 9,086評論 3 38
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,205評論 30 471
  • 前言 由于最近兩個多月,筆者正和小伙伴們忙于對公司新項目的開發,筆者主要負責項目整體架構的搭建以及功能模塊的分工。...
    CoderMikeHe閱讀 27,107評論 74 270
  • 我和海明威是老朋友了。自打他出生在美麗的瓦倫湖旁邊,我就和他為伴,他對我也熟悉,我們無話不說,沒事的時候經常搖曳在...
    淡定的懶懶閱讀 430評論 0 0
  • 我們每個人都有夢想, 有著與眾不同的夢想。 可以是紅色熱情的夢想, 可以是紫色浪漫的夢想, 也可以是綠色生命的夢想...
    薛舒陽閱讀 204評論 0 4