美文网首页专业知识分享(iOS)
iOS - TableViewCell(CollectionVi

iOS - TableViewCell(CollectionVi

作者: 牵着螃蟹逛街走 | 来源:发表于2016-10-15 17:09 被阅读487次

    一. 声明:
    在此文章中以tableView举例, 便于描述.
    二. 问题提出:
    通常我们在写一个tableView时候, 在其协议方法:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    

    在其中会创建多种cell或者从重用池中取出多种cell, 而通常使用index进行判断, 什么时候用哪种cell, 如果这个页面cell的种类少倒还好, 可是如果cell种类繁杂, 那么在这个协议方法中的判断那真是非常折磨人的, 所以参照一些资料, 想出这个cell 的工厂模式.
    三. 想法:
    所谓的工厂模式, 咱们可以这么理解, 一个工厂就是一个加工车间, 如图所示, 送进去原料, 在工厂中进行一系列加工处理, 然后生产出产品.

    工厂模式.png

    用在此处就体现出了面向对象的两个特性: 继承和多态. 我们用同样的思维来思考cell工厂的模式, 我们需要原料, 送进CellFactory, 然后得到对应种类的cell.
    四. 思路:
    同理, 通过数据转化成Model, 再由tableViewCell呈现到界面给用户(CollectionView同理).我们得知道自己需要什么, 当然工厂的产品应该是不同种类的cell, 那么他的原料也应该是不一样的, 那cell种类和什么东西是一一对应的呢, 显而易见是不同种类的model, 这样我们基本的思路就成型了, 创建一个cellFactory, 放入Model, 进行处理, 生成cell


    CellFactory示意图.png

    五. 实现过程:

    1. 第一步:创建基类BaseTableViewCell, 继承于UITableViewCell,
      在BaseTableViewCell.h中声明方法:
    // 赋值方法(在父类实现, 在子类中重写)
    -(void)setModel:(__kindof BaseModel *)model;
    

    在BaseTableViewCell.m中实现方法:

    -(void)setModel:(__kindof BaseModel *)model {
    }
    
    1. 第二步:创建model的基类BaseModel, 继承于NSObject
      在BaseModel.h中声明方法
    +(instancetype)modelWithDictionary:(NSDictionary *)dic;
    

    在BaseModel.m中实现方法

    -(void)setValue:(id)value forKey:(NSString *)key {
        [super setValue:value forKey:key];
    }
    -(void)setValue:(id)value forUndefinedKey:(NSString *)key {
        [super setValue:value forUndefinedKey:key];
    }
    -(id)valueForUndefinedKey:(NSString *)key {  
        return nil;
    }
    -(instancetype)initWithDictionary:(NSDictionary *)dic {
        self = [super init];
        if (self) {      
        [self setValuesForKeysWithDictionary:dic];
        }
        return self;
    }
    +(BaseModel *)modelWithDictionary:(NSDictionary *)dic {
        return [[self alloc] initWithDictionary:dic];
    }
    
    1. 第三步:创建model: StudentModel, 继承于BaseModel
    //写对应的属性, 此处为了简单只写了一个name
    @property (nonatomic, copy) NSString *name;
    
    1. 第四步: 创建tableViewCell: StudentTableViewCell, 继承于BaseTableViewCell
      这里为了方便直接使用xib铺了一个Label, 并重写BaseTableView中的赋值方法:
    -(void)setModel:(StudentModel *)model {
        [super setModel:model];
        _nameLabel.text = model.name;
    }
    
    StudentTableViewCell.png
    1. 第五步: 创建一个工厂类, LTQCellFactory
      在LTQCellFactory.h中声明:
    +(BaseTableViewCell *)createTableViewCellWithModel:(BaseModel *)model
                                              tableView:(UITableView *)tableView;
    

    在LTQCellFactory.m中实现:

    +(BaseTableViewCell *)createTableViewCellWithModel:(BaseModel *)model
                                              tableView:(UITableView *)tableView {
        NSString *modelName = [NSString stringWithUTF8String:object_getClassName(model)];
        NSString *classNameOfCell = [[modelName substringToIndex:modelName.length - 5] stringByAppendingString:@"TableViewCell"];
        BaseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:classNameOfCell];
        return cell;
    }
    
    1. 第六步:引入头文件后,注册Cell并在ViewController中实现
    // 注册StudentTableViewCell
     [_tableView registerNib:[UINib nibWithNibName:@"StudentTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"StudentTableViewCell"];
    
    // 在tableView协议方法中实现
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        BaseModel *model = _dataArr[indexPath.row];
        BaseTableViewCell *cell = [LTQCellFactory createTableViewCellWithModel:(BaseModel *)model tableView:tableView];
        [cell setModel:model];
        return cell;
    }
    

    补充: 由于我自己写的CellFactory是用model的Classname与Cell的Classname进行关联的, 所以在给model和cell的类起名字的时候, 一定要注意, model类名一定要为XXXModel, 而对应的Cell名一定要为XXXTableViewCell或XXXCollectionViewCell,
    而在注册的时候直接用cell的类名作为cell在重用池中的重用标识
    例如:


    起名问题.png

    结论: 这样一来可以在这个dataSource的协议方法中可以节省大量的判断和其他操作过程, 运用了继承和多态, 使得代码更加整洁, 并且高大上了有木有, 如果有问题欢迎留言讨论, 如果我写的文章对你有帮助别忘记点个赞哦😯

    相关文章

      网友评论

      本文标题:iOS - TableViewCell(CollectionVi

      本文链接:https://www.haomeiwen.com/subject/rhgnyttx.html