iOS进阶|适配器模式(解决设置页面)

前言:

现在各大应用类APP都会有个设置页面,设置界面通常是这种


设置页面.PNG

我们可以发现每一个cell长得很相似但是有会有比较小的差别。

效果:

今天我们要实现的效果:

效果.png

看到这种情况最傻的办法是在tableView的代理方法里对indexpath做判断像下面一样👇

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    if(indexPath.seesion == 0){
         if(indexPath.row == 1){
             //todo
        }
         
    }else if (indexPath.seesion == 1){
          if(indexPath.row == 1){
             //todo
        }
    }
}

这种判断的方法维护的成本可想而知,哪天产品经理觉得第二个session应该放在第一个位置,第二天又想放回第二位子,小伙子漫漫加班路等着你的。
如果你经验比较多可能会想到面对模型开发,在model中使用多态,然后在cell中对进来的model判断实现对应的效果可以看我这篇文章关于tableview的cell差异不大的处理方法这也是一种比较好的处理方式(demo),但是这种方式对于没加一种新的cell都会对cell代码有所改动,下面我会介绍一种更好用的解决方案

适配器模式:

今天我们要讲的是试用iOS设计模式中的适配器模式来解决这个问题。

简单讲适配器模式的作用就是在封装控件,接收数据的时候,数据通过中间的适配器处理后再传给控件,主要是在自定义控件时使用。


数据流向
  • 分析:
        我们把设置页面的cell看成一个自定义的view他需要的参数是:iconNameString、titleString、accessibilityView分别为下图的1、2、3。
        除了这个三个看得到的参数我们可能还需要cell点击跳转的目标控制器,或者有的cell点击不是跳转到某个页面而是执行一段代码,这里我们把参数写成block。
cell分析
  • 实现
    1、创建抽象适配器对象
    这里首先创建一个协议AISettingCellAdapterProtocol
#import <Foundation/Foundation.h>
typedef void(^optionBlock)(void);
@protocol AISettingCellAdapterProtocol <NSObject>

- (NSString*)iconNameString;

- (NSString*)titleString;

- (optionBlock)optionBlock;

- (Class)destVC;

- (UIView*)accessibilityView;
@end

协议完成后创建抽象适配器遵循这个协议。由于oc中没有虚函数的说法,我们只有空实现来模拟虚函数

#pragma mark --AISettingCellAdapterProtocol
- (NSString*)iconNameString{
    return nil;
}

- (NSString*)titleString{
    return nil;
}

- (optionBlock)optionBlock{
    return nil;
}

- (Class)destVC{
    return nil;
}

- (UIView*)accessibilityView{
    return nil;
}

2、适配器与数据层建立输入联系
我们需要再创建一个适配器继承刚才创建的抽象适配器。

/**
 装载AISettingModel的适配器
 */
@interface AISettingModelAdapter : AISettingCellAdapter

在这个实体适配器中实现适配方法

#pragma mark --AISettingCellAdapterProtocol
- (NSString*)iconNameString{
    AISettingModel *model = self.data;
    return model.icon;
}

- (NSString*)titleString{
    AISettingModel *model = self.data;
    return model.title;
}

- (optionBlock)optionBlock{
    AISettingModel *model = self.data;
    return model.block;
}

- (Class)destVC{
    AISettingModel *model = self.data;
    return model.destVC;
}

- (UIView*)accessibilityView{
    AISettingModel *model = self.data;
    return model.accessibilityView;
}

建立输入链接

 AISettingModel *model1 = [[AISettingModel alloc]initWithIcon:@"banben" title:@"版本" destClass:[AIDestOneViewController class] andAccessibilityView:imageiew];
        
 AISettingCellAdapter *adapter1 = [[AISettingModelAdapter alloc]initWithData:model1];

3、适配器与视图层建立输出联系

    AISettingTableViewCell *cell      = [AISettingTableViewCell createTableViewCellWithTableView:tableView];
    AISettingCellAdapter *cellAdapter = self.dataSource[indexPath.section][indexPath.row];
    cell.data                         = cellAdapter;

查看完整的源码第16个cell喜欢的给个star

源码位置
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,079评论 25 709
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,311评论 30 472
  • 我的笔记本电脑的工作电压是20V,而我国的家庭用电是220V,如何让20V的笔记本电脑能够在220V的电压下工作?...
    justCode_阅读 5,252评论 0 5
  • 命题1 用一方死亡梗写一篇甜文“你这个游荡在外的孤魂野鬼,我花十年的时间,才把你收了回来。”他得意地对他说,...
    沉肃阅读 4,683评论 0 3
  • 偶尔能看到这样的夫妻:彼此间的言行举止,渗着深厚的爱,不事张扬,恬淡如湖,却透着一种分量很足的魅力,让人心生羡慕。...
    王月冰阅读 2,523评论 0 2