在tableView由于cell类型太多解决方案

- (void)configureCellLogical{
// 根绝Modal里面某个值,进行判断应该创建哪个类的cell
[self addCell:@”zhuanti” class:@”BMZhuanTiCell”];
[self addCell:@”tiezi” class:@”BMTieZiCell”];
}

  • (void)addCell:(NSString )title class:(NSString )className {
    [self.titles addObject:title];
    [self.classNames addObject:className];
    }

#pragma mark - Table view data source

  • (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _titles.count;
    }

  • (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath )indexPath {
    UITableViewCell
    cell = [tableView dequeueReusableCellWithIdentifier:_titles[indexPath.row]];
    if (!cell) { // 根据classNames数创建cell/

    NSString *className = self.classNames[indexPath.row];
    Class class = NSClassFromString(className);
    cell = [[class alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:_titles[indexPath.row]];
    

    }
    cell.textLabel.text = _titles[indexPath.row];
    return cell;
    }
    注:代码可能由于是demo,有小的错误,看主要思想即可.

还有一种通常写法,并且很蛋疼的是:

    if (cellType_SecDown == indexPath.section) {
YYOrderSecondDownCell* cell = [tableView dequeueReusableCellWithIdentifier:StringWithCellType(cellType_SecDown)];
if (!cell) {
cell = [[YYOrderSecondDownCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:StringWithCellType(cellType_SecDown)];
}
return cell;
}else if (cellType_DealStatus == indexPath.section){

….

于是进入了无限的If else判断..不仅如此,再返回cell,计算高度,点击cell都会进行一次判断.也就是这样的逻辑代码会复制多份,并且如果再任何一个地方修改都需要重新再不同的地方去修改自己的逻辑代码..

 

下面贴上抹茶的真实用例,目前没有任何问题,代码也比较美观.性能别以前略有提高

首先是主控制器:

#pragma mark - tableViewDelegate

  • (NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    // 避免创建tableView时有第一个控制器的数据,导致所有创建出来的tableView都返回第一个tableView的数据
    if ([_tabelViews indexOfObject:tableView] != NSNotFound) {
    NSInteger index = [_tabelViews indexOfObject:tableView];
    YYOnlineVC *onlineVCModel = self.onlineVCModels[index];
    return onlineVCModel.feedList.count;
    
    }else{
    return 0;
    
    }
    }
  • (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath )indexPath{
    NSInteger index = [_tabelViews indexOfObject:tableView];
    // 1. 取出cell模型
    YYOnlineVC
    onlineVCModel = self.onlineVCModels[index];
    NSArray feedList = onlineVCModel.feedList;
    // 2. 格式化类名组
    NSArray
    cellClassNames = [YYOnlineBusinessTabHelper formatCellClassArrayWithModelArray:feedList];
    // 3. 创建cell
    YYOnlineTableViewCell cell = [YYOnlineTableViewCell cellWithTableView:tableView withModalArray:cellClassNames indexpath:indexPath];
    // 4. 设置控制器
    cell.viewController = self;
    // 5. 传递数据
    YYOnlinFeed
    model = feedList[indexPath.row];
    [cell updateWithModal:model];
    return cell;
    }
  • (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath{
    NSInteger index = [_tabelViews indexOfObject:tableView];
    // 取对应的table模型
    YYOnlineVC onlineVCModel = self.onlineVCModels[index];
    // 取对应cell 模型
    YYOnlinFeed
    feed = onlineVCModel.feedList[indexPath.row];
    // 根据类数组及索引返回高度;
    NSString *className = [YYOnlineBusinessTabHelper formatCellClassWithModal:feed];
    Class class = NSClassFromString(className);
    return [class heightForModal:feed];
    }
  • (void)tableView:(UITableView )tableView didSelectRowAtIndexPath:(NSIndexPath )indexPath{
    NSInteger index = [_tabelViews indexOfObject:tableView];
    // 取对应的table模型
    YYOnlineVC onlineVCModel = self.onlineVCModels[index];
    // 取对应cell 模型
    YYOnlinFeed
    feed = onlineVCModel.feedList[indexPath.row];
    //下面是具体的跳转
    ….
    }

    这个页面的情况是:有多个tableview,所以索引是感觉tableView在tableView数组中取到索引,然后根据索引再模型数组中取到具体的模型..正常tableView可以省略这部.
    下面是YYOnlineBusinessTabHelper,是页面的VM层

    + (NSArray )formatCellClassArrayWithModelArray:(NSArray )modelArray{
    NSMutableArray classArray = [@[] mutableCopy];
    for (YYOnlinFeed
    feed in modelArray) {

    if (feed.dataType.integerValue == 1) {
        // 商品
        [classArray addObject:@"YYOnlineGoodsCell"];
    }else if (feed.dataType.integerValue == 2){
        // 专题
        [classArray addObject:@"YYOnlineSubjectCell"];
    }
    

    }
    return classArray;
    }

  • (NSString )formatCellClassWithModal:(YYOnlinFeed )feed{
    if (feed.dataType.integerValue == 1) {
    // 商品
    return @"YYOnlineGoodsCell";
    
    }else if (feed.dataType.integerValue == 2){
    // 专题
    return @"YYOnlineSubjectCell";
    
    }
    return @”YYOnlineSubjectCell”;
    }

    这样做的好处是:1.可以减少并且统一控制器的逻辑控制层,以后需要添加其他的cell类型,修改对应cell只需要在这一个地方修改,全控制器通用.

    小提示:ClassArray请务必采用复制粘贴的方式,避免错误.
    下面是主tableViewCell

.h

#import <UIKit/UIKit.h>
@class YYOnlinFeed;
@interface YYOnlineTableViewCell : UITableViewCell
@property (nonatomic ,strong) YYOnlinFeed * feedModel;
@property (nonatomic ,weak)id viewController;

  • (instancetype)cellWithTableView:(UITableView )tableView withModalArray:(NSArray )classNames indexpath:(NSIndexPath *)indexPath;
  • (void)updateWithModal:(YYOnlinFeed *)feedModel;
  • (CGFloat)heightForModal:(YYOnlinFeed *)feedModel;
    @end
    .m
    //
    // YYOnlineTableViewCell.m
    // mocha
    //
    // Created by BM on 16/1/6.
    // Copyright © 2016年 Yao. All rights reserved.
    //

#import “YYOnlineTableViewCell.h”

@implementation YYOnlineTableViewCell

  • (instancetype)cellWithTableView:(UITableView )tableView withModalArray:(NSArray )classNames indexpath:(NSIndexPath )indexPath
    {
    YYOnlineTableViewCell
    cell = [tableView dequeueReusableCellWithIdentifier:classNames[indexPath.row]];
    if (!cell) {

    // 根据classNames数创建cell/
    NSString *className = classNames[indexPath.row];
    Class class = NSClassFromString(className);
    cell = [[class alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:classNames[indexPath.row]];
    

    }

    // code..
    return cell;
    }

  • (void)updateWithModal:(YYOnlinFeed *)feedModel{
    NSLog(@”YYOnlineTableViewCell:请在子类重写 updateWithModal方法”);
    }
  • (CGFloat)heightForModal:(YYOnlinFeed *)feedModel{
    NSLog(@”YYOnlineTableViewCell:请在子类重写 heightForModal方法”);
    return 30;
    }
    具体需要显示的具体cell只需要继承主cell并且重写updateWithModal和heightForModal.

    大概的逻辑如此,这里我知道的

    缺点:

    1.会多引入一个ClassArray数组来存储具体的cell类名

    优点:

    1.逻辑判断集中在一个地方,以便于以后的更改.

    2.主控制器逻辑代码简洁,每一句都是一个主要逻辑,不臃肿.

    3.不需要在数据源3次调用,代码最少1次都重复去写If判断
    还有一种方式是通过协议,不过我还没有实践过.