要实现的效果
查看上面的gif可以看出在这个TableView中实现了UITableViewCell做不同的操作,跳转不同的控制器及辅助视图显示不同的控件
这一切都是代码动态创建的,没有使用Storyboard,XIB
能否有哪位大神告诉我markdown怎么设置文字的颜色呀?我在网上找了半天都没有找到可以用的,求markdown大神带。
言归正传,来说说今天的主题如何实现代码动态实现TableView中实现了UITableViewCell做不同的操作,跳转不同的控制器及辅助视图显示不同的控件
一: 先说说怎么实现辅助视图显示不同的控件吧
我是把需要显示的数据当成一个对象来看待有icon title subtitle 三个属性继承至NSObject ,并实现两个方法(一个实例化方法,一个类方法)
第一步:
.h文件
@interface LYSettingItem : NSObject
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subTitle;
-(instancetype)initWithIcon:(NSString *)icon WithTitle:(NSString *)title;
+(instancetype)initWithIcon:(NSString *)icon WithTitle:(NSString *)title;
@end
icon是UITableViewCell的imageView
title是UITableViewCell的textLabel
subTitle是UITableViewCell的detailTextLabel
.m文件
@implementation LYSettingItem
- (instancetype)initWithIcon:(NSString *)icon WithTitle:(NSString *)title
{
self = [super init];
if (self) {
self.icon = icon;
self.title = title;
}
return self;
}
+(instancetype)initWithIcon:(NSString *)icon WithTitle:(NSString *)title {
return [[self alloc]initWithIcon:icon WithTitle:title];
}
@end
感觉上面说的这些都跟辅助视图显示不同的控件貌似没有半毛钱的关系,别急!!!!我们要实现辅助视图显示不同的控件这是第一步,我们把它当成一个基类(默认辅助视图样式)
假如我们现在需要在辅助试图显示一个UISwitch
第二步:
我们需要自定义一个Cell,实现一个类方法注册我们的UITableViewCell
#import
@interface LYSettingCell : UITableViewCell
+(instancetype)cellWithTableView:(UITableView *)tableView;
@end
实现一个类方法注册我们的UITableViewCell
+ (instancetype)cellWithTableView:(UITableView *)tableView {
static NSString *cellID = @"settingCell";
LYSettingCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[LYSettingCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
}
return cell;
}
第三步:
我们再创建一个类继承至LYSettingItem 取名为LYSettingSwitchItem
@interface LYSettingSwitchItem : LYSettingItem
第四步:
来到我们的UITableViewController
定义一个可变数组
@property (nonatomic, strong) NSMutableArray *cellData;///<表格数据 存储LYSettingItem
在viewDidLoad函数里面写我们要在tableViewCell中显示的数据
(void)viewDidLoad {
[super viewDidLoad];
//初始化数据
//第一组
LYSettingItem *item1 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"推送和提醒"];
LYSettingItem *item2 = [LYSettingSwitchItem itemWithIcon:@"handShake" title:@"摇一摇机选"];
LYSettingItem *item3 = [LYSettingSwitchItem itemWithIcon:@"handShake" title:@"声音和效果"];
NSArray *group1 = @[item1,item2,item3];
[self.cellData addObject:group1];
//第二组
LYSettingItem *item4 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"检查版本更新"];
LYSettingItem *item5 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"帮助"];
LYSettingItem *item6 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"分享"];
LYSettingItem *item7 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"查看消息"];
LYSettingItem *item8 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"产品推荐"];
LYSettingItem *item9 = [LYSettingArrowItem itemWithIcon:@"handShake" title:@"关于"];
NSArray *group2 = @[item4,item5,item6,item7,item8,item9];
[self.cellData addObject:group2];
}
完成UITableViewController数据源numberOfSectionsInTableView和numberOfRowsInSection函数的回答
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.cellData.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *group = self.cellData[section];
return group.count;
}
第五步:
回到我们的LYSettingCell.h文件,@class我们的基类(LYSettingItem),并且公开一个LYSettingItem对象(用于设置显示数据)
@class LYSettingItem;
@property (nonatomic, strong) LYSettingItem *item;
回到.m文件
这里的mySwitch,myArrow 我们使用懒加载的方式(避免多次创建)
在.m文件
/** 用于设置UISwitch的tag,根据tag做不同的操作 */
static NSInteger switchTag = 0;
@interface LYSettingCell()
@property (nonatomic, strong) UIImageView *myArrow;///<箭头
@end
懒加载(只懒加载不用于操作的控件,比如label,imageView...)
- (UIImageView *)myArrow {
if (!_myArrow) {
_myArrow = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"CellArrow"] ];
}
return _myArrow;
}
重写item的set函数
关键 通过isKindOfClass:函数判断
- (void)setItem:(LYSettingItem *)item {
if (_item!=item) {
_item = item;
self.textLabel.text = item.title;
if (_item.icon) {
self.imageView.image = [UIImage imageNamed:item.icon];
}
//设置辅助视图
//通过子类判断
if ([item isKindOfClass:[LYSettingSwitchItem class ]]) { //Switch 开关
switchTag ++;
UISwitch *mySwitch = [UISwitch new];
mySwitch.tag = switchTag;
[mySwitch addTarget:self action:@selector(valueChange:) forControlEvents:UIControlEventValueChanged];
//设置开关的状态
mySwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:self.item.title];
self.accessoryView = mySwitch;
self.selectionStyle = UITableViewCellSelectionStyleNone;//设置Cell选中的样式
} else if ([item isKindOfClass:[LYSettingArrowItem class]]) {
//图片
self.accessoryView = self.myArrow;
}
}
}
switch事件
- (void)valueChange:(UISwitch *)sender {
NSLog(@"%li",sender.tag);
NSLog(@"%@",sender.isOn?@"打开":@"关闭");
//把开关状态保存到用户偏好设置
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:sender.isOn forKey:self.item.title];
[defaults synchronize];//保存同步
}
第六步:
最后回到UITableViewController完成数据的显示
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LYSettingCell *cell = [LYSettingCell cellWithTableView:tableView];
//获取组模型显示数据
NSArray *group = self.cellData[indexPath.section];
//获取行模型数据
LYSettingItem *items = group[indexPath.row];
//显示数据
cell.item = items;
return cell;
}
第七步:
CMD + R
总结:实现辅助视图显示不同的控件
主要是通过LYSettingItem的子类用isKindOfClass:函数来判断该cell的accessoryView(辅助视图)应该显示什么控件
补充一点:控件不做任何响应操作的直接进行懒加载即可,但是要与用户进行交互的,则需要一个生成一个,并设置其tag,根据tag来区分响应操作。如文中的UISwitch控件。
内容写得不好,还请大神多多指点。
谁有更好的办法,请分享一下!