采用工厂模式处理同一页面不同Cell样式

  • Post author:
  • Post category:其他


前言:

当同一个列表页面,cell样式很多时,要做出很多逻辑判断:如图页面一和页面二:

一般情况,要在cellForRow中做大量的判断,这样会导致结构不清晰、及其繁琐、不易阅读。

页面一一般代码会如下繁琐:

NSString *idntifier = [NSString stringWithFormat:@"%ld,%ld",(long)indexPath.row,(long)indexPath.section];
MedicalHistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:idntifier];
if (indexPath.row == 14 || indexPath.row == 18) {
    if (cell == nil) {
        cell = [[MedicalHistoryCell alloc]initWithMedicalStyle:MedicalCellStyleSelect reuseIdentifier:idntifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }
    [cell upDataWithString:medicalHistoryArray[indexPath.row]];
    return cell;
}else if (indexPath.row == 19 )
{
    if (cell == nil) {
        cell = [[MedicalHistoryCell alloc]initWithMedicalStyle:MedicalCellStyleInput reuseIdentifier:idntifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        }
        [cell upDataWithString:medicalHistoryArray[indexPath.row]];
        return cell;
}else
{
    if (cell == nil) {
        cell = [[MedicalHistoryCell alloc]initWithMedicalStyle:MedicalCellStyleDefault reuseIdentifier:idntifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.indexPath = indexPath;
        cell.delegate = self;
        }
        [cell upDataWithString:medicalHistoryArray[indexPath.row]];
        return cell;
}
复制代码

采用工厂模式的思想,即可简单化:

那什么是工厂模式呢?

一个工厂就是一个加工车间,我们送各种原料,根据原料的不同,会生产各种产品。 同理我们可以把数据转化为model,然后根据model不同,输出我们想要的各个风格cell。 cell就和自己的model一一对应,创建一个cellFactory ,放入model,进行处理,生成我们需要的cell。 上图二页面为例: 实现过程:

(1)构建基类BaseModel和PersonalBaseCell

cell中,根据runtime获取类名,进行构建各自cell,代码如下:

#import "PersonalBaseCell.h"
#import <objc/runtime.h>

@implementation PersonalBaseCell

+ (instancetype)configCellWithModel:(BaseModel*)model
{
  //获取model名称
  NSString *modelName = [NSString stringWithUTF8String:object_getClassName(model)];
  NSString *cell_Name = [NSString stringWithFormat:@"%@", [modelName stringByReplacingOccurrencesOfString:@"Model" withString:@"Cell"]];
  //使用runtime通过类名称获取对象并且创建
  PersonalBaseCell *cell = [[objc_getClass(cell_Name.UTF8String) alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:modelName];
  return cell;
}

+ (CGFloat)cellHeightWithModel:(BaseModel *)model
{
  //获取model名称
  NSString *modelName = [NSString stringWithUTF8String:object_getClassName(model)];
  //根据Model的名字拼接cell获取Cell类名
  NSString *cellName = [NSString stringWithFormat:@"%@", [modelName stringByReplacingOccurrencesOfString:@"Model" withString:@"Cell"]];
   return [objc_getClass(cellName.UTF8String) cellHeightWithModel:model];
}
@end
复制代码

(2)model中根据标示(可和后台协商,解析数据)构建构建子模块model,代码如下:

#import "BaseModel.h"
#import "HeadModel.h"
#import "InputModel.h"
#import "ShowModel.h"
#import "TextAndImageModel.h"
@implementation BaseModel

+ (instancetype)modelWithDictionary:(NSDictionary *)dictionary{
    
    BaseModel *model = nil;
    if ([[dictionary objectForKey:@"tag"] isEqualToString:@"001"]) {
        model = [[HeadModel alloc]init];
    }else if ([[dictionary objectForKey:@"tag"] isEqualToString:@"002"]) {
        model = [[InputModel alloc]init];
    }else if ([[dictionary objectForKey:@"tag"] isEqualToString:@"003"]) {
        model = [[TextAndImageModel alloc]init];
    }else{
        model = [ShowModel new];
    }
    [model setValuesForKeysWithDictionary:dictionary];
    return model;
}

@end
复制代码

(3)其他子cell复写父类方法和数据赋值(运用多态和继承思想)

最后controller代码简洁明了,请求数据,根据model,由一个类,产生不同对象,体现工厂模式思想、主要代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    BaseModel *model = self.dataArray[indexPath.row];
    PersonalBaseCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithUTF8String:object_getClassName(model)]];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    if (cell == nil) {
        cell = [PersonalBaseCell configCellWithModel:model];
    }
    [cell setModel:model];
    return cell;
}
复制代码

转载于:https://juejin.im/post/5c6b7685f265da2dd8688883