背景介绍
一个表格,有多种cell,这种页面越来越常见
取得cell的代理函数,会有一大串的if比较
确定cell高度的代理函数,会有一大串的if比较
一种方法
利用Object-C的动态特性,主要是
Class _Nullable NSClassFromString(NSString *aClassName)
将cell的类名放在数据源中,可以提供一个父类,命名好类名的属性。
利用继承,提供一个cell的父类,命名好需要用到的函数,在具体的子类中实现。
使用的时候,就可以用
Class _Nullable NSClassFromString(NSString *aClassName)
,避免大量的if判断。
例子代码
BaseModel.h
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject
// 具体调用的cell的类名
@property (nonatomic, strong) NSString *className;
@end
BaseTableViewCell.h
#import <UIKit/UIKit.h>
#import "BaseModel.h"
@interface BaseTableViewCell : UITableViewCell
// cell生成函数
+ (instancetype)cellWithTableView:(UITableView *)tableView;
// 更新表格内容
- (void)updateCellWithModel:(BaseModel*)model;
// 表格高度
+ (CGFloat)rowHeight:(BaseModel*)model;
@end
BaseTableViewCell.m
#import "BaseTableViewCell.h"
#define kDefaultCellHeight 44
@implementation BaseTableViewCell
#pragma mark - interface
// 这样写可以隐藏reuseIdentifier字符串
+ (instancetype)cellWithTableView:(UITableView *)tableView {
static NSString *reuseIdentifier = @"BaseTableViewCell";
BaseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (nil == cell) {
cell = [[BaseTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}
return cell;
}
- (void)updateCellWithModel:(BaseModel *)model {
if (nil == model) {
return;
}
// 做其他内容更新操作
// 重新autolayout
[self setNeedsUpdateConstraints];
}
+ (CGFloat)rowHeight:(HHDiscoveryHomeModel *)model {
return kDefaultCellHeight;
}
#pragma mark - life cycle
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// 创建UI元素,设置属性,并加到cell的contentView
}
return self;
}
@end
xxxController.m
#import "BaseTableViewCell.h"
@interface xxxController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray <BaseModel *> *modelArray;
@end
@implementation xxxController // 具体的使用者
#pragma mark - UITableViewDataSource, UITableViewDelegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BaseModel *model = self.modelArray[indexPath.row];
Class classFromName = NSClassFromString(model.className);
BaseTableViewCell *cell = [classFromName cellWithTableView:tableView];
[cell updateCellWithModel:model];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.modelArray.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
BaseModel *model = self.modelArray[indexPath.row];
Class cell = NSClassFromString(model.className);
return [cell rowHeight:model];
}
@end