前言:
现在各大应用类APP都会有个设置页面,设置界面通常是这种
我们可以发现每一个cell长得很相似但是有会有比较小的差别。
效果:
今天我们要实现的效果:
看到这种情况最傻的办法是在
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。
- 实现
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