如何处理一个tableView中同种model多种cell相同逻辑的情况?

如何处理一个tableView中同种model多种cell相同逻辑的情况?_第1张图片
iu的图片用完了,用我允的代替一下

这是购物车页面:


如何处理一个tableView中同种model多种cell相同逻辑的情况?_第2张图片

有4种cell:

  1. 一般商品cell
  2. 带赠品的商品cell
  3. 满赠商品cell
  4. 补货中商品cell

一般来说,有多少种cell就要自定义多少种cell,但是这4种cell又有相同的逻辑处理,如点击商品图片进入商品详情页。如何处理既不会让代码显得啰嗦又不会因为继承导致耦合度变高?

我的做法是先封装一个基类cell,这个cell只封装逻辑处理相关代码

#import 
#import "CQShopCartCellModel.h"

@class CQShopCartGoodsCell;
@protocol CQShopCartGoodsCellDelegate 

@optional

/** 选中按钮点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell chooseButtonDidClick:(UIButton *)chooseButton;
/** 加按钮点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell addButtonDidClick:(UIButton *)addButton;
/** 减按钮点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell minusButtonDidClick:(UIButton *)minusButton;
/** 商品图片点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell goodsImageViewDidTap:(UIImageView *)goodsImageView;

@end

@interface CQShopCartGoodsCell : UITableViewCell

@property (nonatomic, weak) id  delegate;
@property (nonatomic, strong) CQShopCartCellModel *model;

@end

然后4种cell再继承这个基类cell。

在controller中:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    CQShopCartGoodsCell *goodsCell = nil;
    CQShopCartCellModel *model = nil;
    switch (indexPath.section) {
        case 0: // 普通商品
        {
            model = self.commonGoodsArray[indexPath.row];
            if (model.giftsArray.count > 0) {
                // 有赠品的商品
                goodsCell = [tableView dequeueReusableCellWithIdentifier:CQShopcartHaveGiftGoodsCellID forIndexPath:indexPath];
            } else {
                // 无赠品的商品
                goodsCell = [tableView dequeueReusableCellWithIdentifier:CQShopcartNoGiftGoodsCellID forIndexPath:indexPath];
            }
        }
            break;
            
        case 1: // 满赠商品
        {
            model = self.giftGoodsArray[indexPath.row];
            goodsCell = [tableView dequeueReusableCellWithIdentifier:CQShopcartGiftGoodsCellID forIndexPath:indexPath];
        }
            break;
            
        case 2: // 补货中商品
        {
            model = self.emptyGoodsArray[indexPath.row];
            goodsCell = [tableView dequeueReusableCellWithIdentifier:CQShopcartEmptyGoodsCellID forIndexPath:indexPath];
        }
            break;
            
        default:
        {
            goodsCell = [[CQShopCartGoodsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"defaultCell"];
        }
            break;
    }
    goodsCell.model = model;
    goodsCell.delegate = self;
    return goodsCell;
}
如何处理一个tableView中同种model多种cell相同逻辑的情况?_第3张图片

一目了然。

欢迎大家说出自己的想法。


补充

详细解释一下。

这是cell对应的文件夹:

如何处理一个tableView中同种model多种cell相同逻辑的情况?_第4张图片

商品cell基类的.h文件:

#import 
#import "CQShopCartCellModel.h"

@class CQShopCartGoodsCell;
@protocol CQShopCartGoodsCellDelegate 

@optional

/** 选中按钮点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell chooseButtonDidClick:(UIButton *)chooseButton;
/** 加按钮点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell addButtonDidClick:(UIButton *)addButton;
/** 减按钮点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell minusButtonDidClick:(UIButton *)minusButton;
/** 商品图片点击 */
- (void)goodsCell:(CQShopCartGoodsCell *)goodsCell goodsImageViewDidTap:(UIImageView *)goodsImageView;

@end

@interface CQShopCartGoodsCell : UITableViewCell

@property (nonatomic, weak) id  delegate;
@property (nonatomic, strong) CQShopCartCellModel *model;

@end

商品cell基类的.m文件没做任何处理。

不带赠品的商品cell(继承自商品cell基类):

#pragma mark - 构造方法
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self setUpUI];
    }
    return self;
}

#pragma mark - UI搭建
/** UI搭建 */
- (void)setUpUI {
    // 根据UI图搭建UI
}

#pragma mark - model 赋值
- (void)setModel:(CQShopCartCellModel *)model {
    super.model = model;
    // 相关赋值
}

#pragma mark - 选中按钮点击
/** 选中按钮点击 */
- (void)chooseButtonClicked:(UIButton *)sender {
    if ([self.delegate respondsToSelector:@selector(goodsCell:chooseButtonDidClick:)]) {
        [self.delegate goodsCell:self chooseButtonDidClick:sender];
    }
}

#pragma mark - 商品图片点击
/** 商品图片点击 */
- (void)goodsImageViewTaped:(UIImageView *)goodsImageView {
    if ([self.delegate respondsToSelector:@selector(goodsCell:goodsImageViewDidTap:)]) {
        [self.delegate goodsCell:self goodsImageViewDidTap:goodsImageView];
    }
}

#pragma mark - 商品“加”按钮点击
/** 商品“加”按钮点击 */
- (void)addButtonClicked:(UIButton *)addButton {
    if ([self.delegate respondsToSelector:@selector(goodsCell:addButtonDidClick:)]) {
        [self.delegate goodsCell:self addButtonDidClick:addButton];
    }
}

#pragma mark - 商品“减”按钮点击
/** 商品“减”按钮点击 */
- (void)minusButtonClicked:(UIButton *)minusButton {
    if ([self.delegate respondsToSelector:@selector(goodsCell:minusButtonDidClick:)]) {
        [self.delegate goodsCell:self minusButtonDidClick:minusButton];
    }
}

注意那几个事件处理

补货中商品cell(还是继承商品cell基类):

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // UI搭建
        [self setUpUI];
    }
    return self;
}

#pragma mark - UI搭建
/** UI搭建 */
- (void)setUpUI {
    // 根据UI图搭建UI
}

#pragma mark - 赋值model
/** 赋值model */
- (void)setModel:(CQShopCartCellModel *)model {
    super.model = model;
    
    // 相关赋值
}

#pragma mark - 点击图片进入详情页
/** 点击图片进入详情页 */
- (void)goodsImageViewTaped {
    if ([self.delegate respondsToSelector:@selector(goodsCell:goodsImageViewDidTap:)]) {
        [self.delegate goodsCell:self goodsImageViewDidTap:self.goodsImageView];
    }
}

还是注意事件处理

其余两种cell的处理类似

总结

将协议写到基类cell里,在controller中只需对应基类cell的协议就可以了:

如何处理一个tableView中同种model多种cell相同逻辑的情况?_第5张图片

这样就避免了写重复的事件处理,并且代码看起很整洁清晰。

2017年11月16日更新

今天才知道,我这种写法就是传说中的抽象基类。

你可能感兴趣的:(如何处理一个tableView中同种model多种cell相同逻辑的情况?)