如何处理一个tableView中同种model多种cell相同逻
2017-11-13 本文已影响721人
无夜之星辰

这是购物车页面:

有4种cell:
1.一般商品cell
2.带赠品的商品cell
3.满赠商品cell
4.补货中商品cell
一般来说,有多少种cell就要自定义多少种cell,但是这4种cell又有相同的逻辑处理,如点击商品图片进入商品详情页。如何处理既不会让代码显得啰嗦又不会因为继承导致耦合度变高?
我的做法是先封装一个基类cell,这个cell只封装逻辑处理相关代码:
#import <UIKit/UIKit.h>
#import "CQShopCartCellModel.h"
@class CQShopCartGoodsCell;
@protocol CQShopCartGoodsCellDelegate <NSObject>
@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 <CQShopCartGoodsCellDelegate> delegate;
@property (nonatomic, strong) CQShopCartCellModel *model;
@end
然后4种cell再继承这个基类cell。
在controller中:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CQShopCartGoodsCell *goodsCell = [tableView dequeueReusableCellWithIdentifier:@""];
CQShopCartCellModel *model = nil;
switch (indexPath.section) {
case 0: // 普通商品
{
model = self.commonGoodsArray[indexPath.row];
if (goodsCell == nil) {
if (model.giftsArray.count > 0) {
// 有赠品的商品
goodsCell = [[CQShopCartHaveGiftGoodsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQShopcartHaveGiftGoodsCellID];
} else {
// 无赠品的商品
goodsCell = [[CQShopCartNoGiftGoodsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQShopcartNoGiftGoodsCellID];
}
}
}
break;
case 1: // 满赠商品
{
model = self.giftGoodsArray[indexPath.row];
goodsCell = (goodsCell ?: [[CQShopCartGiftGoodsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQShopcartGiftGoodsCellID]);
}
break;
case 2: // 补货中商品
{
model = self.emptyGoodsArray[indexPath.row];
goodsCell = (goodsCell ?: [[CQShopCartEmptyGoodsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQShopcartEmptyGoodsCellID]);
}
break;
default:
break;
}
goodsCell.model = model;
goodsCell.delegate = self;
return goodsCell;
}

一目了然。
欢迎大家说出自己的想法。
补充
详细解释一下。
这是cell对应的文件夹:

商品cell基类
的.h文件:
#import <UIKit/UIKit.h>
#import "CQShopCartCellModel.h"
@class CQShopCartGoodsCell;
@protocol CQShopCartGoodsCellDelegate <NSObject>
@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 <CQShopCartGoodsCellDelegate> 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的协议就可以了:

这样就避免了写重复的事件处理,并且代码看起很整洁清晰。
2017年11月16日更新
今天才知道,我这种写法就是传说中的抽象基类。