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

来源:互联网 发布:java long转int 编辑:程序博客网 时间:2024/06/15 01:04

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

所以要将“设置类”控制器抽出来一个父类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
0 0
原创粉丝点击