背景介紹
一個表格,有多種cell,這種頁面越來越常見
取得cell的代理函數(shù),會有一大串的if比較
確定cell高度的代理函數(shù),會有一大串的if比較
一種方法
利用Object-C的動態(tài)特性,主要是
Class _Nullable NSClassFromString(NSString *aClassName)將cell的類名放在數(shù)據(jù)源中,可以提供一個父類,命名好類名的屬性。
利用繼承,提供一個cell的父類,命名好需要用到的函數(shù),在具體的子類中實現(xiàn)。
使用的時候,就可以用
Class _Nullable NSClassFromString(NSString *aClassName),避免大量的if判斷。
例子代碼
BaseModel.h
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject
// 具體調(diào)用的cell的類名
@property (nonatomic, strong) NSString *className;
@end
BaseTableViewCell.h
#import <UIKit/UIKit.h>
#import "BaseModel.h"
@interface BaseTableViewCell : UITableViewCell
// cell生成函數(shù)
+ (instancetype)cellWithTableView:(UITableView *)tableView;
// 更新表格內(nèi)容
- (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;
}
// 做其他內(nèi)容更新操作
// 重新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) {
// 創(chuàng)建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