”设置类“包含多控制器的TableViewController的详细使用

一、由于“设置类”控制器就是为了导航多种设置功能,所以它的主界面会包含多项设置,而且每一项点击进去又会包含多项子设置。
这里写图片描述

所以要将“设置类”控制器抽出来一个父类BaseSettingController(属于TableViewController),让每一个具有多项导航功能的tableViewController都继承于这个父类。
在这个父类要实现所有“设置类”都具有的基本功能:
1、 有一个属性用于保存表数据

//保存表的数据
@property (nonatomic,strong) NSMutableArray *cellData;//暴露出来,保证子类都能继承这个属性

2、要实现数据源和代理方法。具体的表数据则由继承自它的子类具体实现,不在BaseSettingController中实现。

BaseSettingController的实现:

//  FYBaseSettingVC.m
#import "FYBaseSettingVC.h"
#import "FYSettingItem.h"
#import "FYSettingItemArrow.h"
#import "FYSettingItemSwitch.h"
#import "MBProgressHUD+MJ.h"
#import "FYSettingGroup.h"

@implementation FYBaseSettingVC

//设置cell的分组样式
- (instancetype)init{
    if (self = [super initWithStyle:UITableViewStyleGrouped]) {
        //
    }
    return self;
}

//懒加载
- (NSMutableArray *)cellData{
    if (!_cellData) {
        _cellData = [NSMutableArray array];
    }
    return _cellData;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    //返回有多少个分组
    return self.cellData.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    //返回每一组的行数,先获取组,再获取该组的行数
    FYSettingGroup *group = self.cellData[section];
    return group.items.count;
}

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

    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }

    // 获取行模型数据
    FYSettingGroup *group = self.cellData[indexPath.section];//先获取组

    FYSettingItem *item = group.items[indexPath.row];//再获取组中的数据

    if (item.icon) {
        cell.imageView.image = [UIImage imageNamed:item.icon];
    }

    cell.textLabel.text = item.title;

    //根据不同的行模型的类型确定辅助标志
    if ([item isKindOfClass:[FYSettingItemArrow class]]) {//判断不同行的item的类名
        cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellArrow"]];
    } else if ([item isKindOfClass:[FYSettingItemSwitch class]]){
        cell.accessoryView = [[UISwitch alloc]init];
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    // 获取行模型数据
    FYSettingGroup *group = self.cellData[indexPath.section];//先获取组
    FYSettingItem *item = group.items[indexPath.row];//再获取组中的数据

    if (item.operation) {//判断是否有特殊操作
        item.operation();//有特殊操作执行特殊操作
    } else if(item.vcClass) {//判断该行cell的vcClass属性是否有值,有值说明点击该行需要跳转
        id vc = [[item.vcClass alloc]init];//创建跳转控制器并加载
        [self.navigationController pushViewController:vc animated:YES];
    }
}
//设置每组的头标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    // 获取组数据
    FYSettingGroup *group = self.cellData[section];//先获取组
    return group.headerTitle;

}

//设置每组的尾标题
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{

    // 获取组数据
    FYSettingGroup *group = self.cellData[section];//先获取组
    return group.footerTitle;
}
@end

二、为每一行数据建模型、为每一组数据建模型
这里写图片描述
要知道cell一般会包含图标、标题、辅助图标等,但又不是有所有的cell都长得一样,所以创建行数据模型时要考虑:点击该行是否需要跳转(即行模型要有一个属性决定是否能跳转到下一个控制器);辅助标志不一样,有的要显示箭头有的要显示开关(如何判断?可以设计两种行模型,一种是带箭头的SettingItemArrow,一种是带开关的SettingItemSwitch,这两种模型都继承自父类SettingItem,根据不同的类新显示不同的辅助标志)。

行数据模型头文件:

//  FYSettingItem.h
#import <Foundation/Foundation.h>
typedef void (^OperationBlock)();//定义一个block

@interface FYSettingItem : NSObject

@property (nonatomic,copy) NSString *icon;//cell的图标
@property (nonatomic,copy) NSString *title;//cell的标题

//添加一个Class属性,用于标注点击cell时将跳转到的下一个控制器的类型
@property (nonatomic,assign) Class vcClass;
//添加一个block属性,保存操作,因为有的cell点击后不是跳转到别的控制器而是执行一段代码,比如“检查软件更新”选项
@property (nonatomic,copy) OperationBlock operation;

- (instancetype)initWithIcon:(NSString *)icon title:(NSString *)title;

+ (instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title;

/**
 *  带有控制器类的item模型
 */
+ (instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title vcClass:(Class)vcClass;
@end

行数据模型的实现:

//  FYSettingItem.m

#import "FYSettingItem.h"

@implementation FYSettingItem
//对象方法
- (instancetype)initWithIcon:(NSString *)icon title:(NSString *)title{

    if ([super init]) {
        self.icon = icon;
        self.title = title;
    }

    return  self;
}

//类方法
+ (instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title{


    return [[self alloc] initWithIcon:icon title:title];
}

+ (instancetype)itemWithIcon:(NSString *)icon title:(NSString *)title vcClass:(Class)vcClass{

    FYSettingItem *item = [[self alloc] initWithIcon:icon title:title];
    item.vcClass = vcClass;
    return item;
}

@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值