(十八)TableView实践(多组汽车品牌展示)
对于多组数据,可能会用到模型的嵌套。
例如多组汽车,每组是一个模型,组内有多辆车的信息,每辆车的信息也是一个模型,相当于模型中有模型。
可以看到,每个item是一个字典,这要创建一个模型,而模型内部的cars数组中每一个元素又是一个字典,即还需要一个模型。
Tip:命名的时候,关于描述的不要写description,否则会把系统的这个方法覆盖,一般是写desc。
取出一个模型数组中的所有某成员(key)值的方法:
假如group是一个模型,那么[group valueForKeyPath:@"title"] 表示找出group的title的值。
如果groups是一个模型数组,那么[group valueForKeyPath:@"title"] 表示把数组中每一个元素的title找到,并装入一个数组返回。
(KVC,Key-Value-Coding)valueForKey与valueForKeyPath的区别:前者只能取直接属性,不能取间接属性,例如group中有title,两者都可以取,groups没有title属性,只有valueForKeyPath方法才能进入group取到title,因此应该多用valueForKeyPath。
关键细节:
Car模型的实现:
@interface Car : NSObject /** * 名称 */ @property (nonatomic, copy) NSString *name; /** * 图标 */ @property (nonatomic, copy) NSString *icon; + (instancetype)carWithDict:(NSDictionary *)dict; - (instancetype)initWithDict:(NSDictionary *)dict; @end
@implementation Car + (instancetype)carWithDict:(NSDictionary *)dict{ return [[self alloc] initWithDict:dict]; } - (instancetype)initWithDict:(NSDictionary *)dict{ if (self = [super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } @endCarGroup的实现:注意模型内有模型的时候,这个外层模型的初始化方法不能再简单的用KVC来实现,因为KVC得到的是字典,应该手动取出该字典,生成car模型后再装回去,否则成员变量cars里面装的会是字典而不是模型。
@interface CarGroup : NSObject /** * 组标题 */ @property (nonatomic, copy) NSString *title; /** * 存放所有汽车品牌,装的是车的数据模型。 */ @property (nonatomic, strong) NSArray *cars; + (instancetype)groupWithDict:(NSDictionary *)dict; - (instancetype)initWithDict:(NSDictionary *)dict; @end
@implementation CarGroup + (instancetype)groupWithDict:(NSDictionary *)dict{ return [[self alloc] initWithDict:dict]; } - (instancetype)initWithDict:(NSDictionary *)dict{ if (self = [super init]) { //取出汽车的字典数组 NSArray *dictArray = dict[@"cars"]; NSMutableArray *carArray = [NSMutableArray array]; for (NSDictionary *dict in dictArray) { Car *car = [[Car alloc] initWithDict:dict]; [carArray addObject:car]; } self.cars = carArray; self.title = dict[@"title"]; } return self; } @end
在控制器里将所有组声明为groups,然后通过懒加载初始化。
这里的一个新知识是在TableView上增加右侧的索引,使用如下的方法:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{ return [self.groups valueForKeyPath:@"title"]; }
可以看到要返回的是字符串数组,为了得到groups中的每一个group的title,使用KVC的valueForKeyPath属性间接取得所有title的值并且生成一个字符串数组返回。
索引的跳转和字符串无关,字符串数组的index和组号对应,点击对应的字符串会跳去当前index所在的组号的组。