【iOS开发-60】案例学习:多组数据的tableView设置、增加右侧组索引、多层数据模型设置以及valueForKeyPath

效果:


这里的数据模型有两层:每一组汽车是一层模型,每一组里面的每一行汽车品牌也是一层模型。

(1)我们先创建一个WSCars模型。

在WSCars.h中:

#import <Foundation/Foundation.h>

@interface WSCars : NSObject
@property(nonatomic,copy) NSString *icon;
@property(nonatomic,copy) NSString *name;

+(WSCars *)carsWithDict:(NSDictionary *)dict;
-(WSCars *)initWithDict:(NSDictionary *)dict;
@end

在WSCars.m中:

#import "WSCars.h"

@implementation WSCars


+(WSCars *)carsWithDict:(NSDictionary *)dict{
    return [[self alloc]initWithDict:dict];
}

-(WSCars *)initWithDict:(NSDictionary *)dict{
    if ([super init]) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}

@end

(2)再创建一个汽车组模型,WSCarGroup。

在WSCarGroup.h中:

#import <Foundation/Foundation.h>

@interface WSCarGroup : NSObject
@property(nonatomic,copy) NSString * title;
@property(nonatomic,strong) NSArray *cars;

+(WSCarGroup *)carGroupWithDict:(NSDictionary *)dict;
-(WSCarGroup *)initWithDict:(NSDictionary *)dict;
@end

在WSCarGroup.m中:(此处做了1次字典转模型,即把每个汽车数据转成WSCars对象)

#import "WSCarGroup.h"
#import "WSCars.h"
@implementation WSCarGroup

+(WSCarGroup *)carGroupWithDict:(NSDictionary *)dict{
    return [[self alloc]initWithDict:dict];
}

-(WSCarGroup *)initWithDict:(NSDictionary *)dict{
    if ([super init]) {
        self.title=dict[@"title"];
        
        NSArray *dictArray=dict[@"cars"];
        NSMutableArray *muArray=[[NSMutableArray alloc]init];
        for (NSDictionary * dic in dictArray) {
            WSCars *car=[[WSCars alloc]initWithDict:dic];
            [muArray addObject:car];
        }
        self.cars=muArray;
    }
    return self;
}

@end

(3)然后在ViewController.m中,定义数组,并且把字典转模型

@property (nonatomic,strong) NSArray *carsArray;

//字典转模型
- (NSArray *)carsArray{
    if (_carsArray==nil) {
        NSString *path=[[NSBundle mainBundle]pathForResource:@"cars_total.plist" ofType:nil];
        NSArray *totalArray=[NSArray arrayWithContentsOfFile:path];
        NSMutableArray *muArray=[[NSMutableArray alloc]init];
        for (NSDictionary *dict in totalArray) {
            WSCarGroup *carGroup=[[WSCarGroup alloc]initWithDict:dict];
            [muArray addObject:carGroup];
        }
        _carsArray=muArray;
    }
    return _carsArray;
}

数组工作至此完成。


(4)拖拽一个tableView,并且定义成变量。这个控制器被当成数据源,所以遵守协议。

@interface ViewController ()<UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableView;

(5)并且把数据源设置成当前控制器,顺便设置一下行高

- (void)viewDidLoad {
    //设置数据源
    self.tableView.dataSource=self;
    //设置行高
    self.tableView.rowHeight=60;
    [super viewDidLoad];
}

(6)设置tableView的组、行和cell数据和组名字。

//设置多少组
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return self.carsArray.count;
}
//设置多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    WSCarGroup *carGroup=self.carsArray[section];
    return carGroup.cars.count;
}
//设置cell内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    //先缓存池,性能优化
    static NSString *ID=@"car";
    UITableViewCell *cell=[self.tableView dequeueReusableCellWithIdentifier:ID];
    if (cell==nil) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    //取出数据
    WSCarGroup *carGroup=self.carsArray[indexPath.section];
    WSCars *cars=carGroup.cars[indexPath.row];
    //赋值给cell
    cell.textLabel.text=cars.name;
    cell.imageView.image=[UIImage imageNamed:cars.icon];
    return cell;
}
//设置组名
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    WSCarGroup *carGroup=self.carsArray[section];
    return carGroup.title;
}

(7)设置组索引

-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    //需要返回一个数组
    //用valueForKey只能在本层级字典中查找,而self.carsArray是数组,且没有title关键字
    //用valueForKeyPath可以在本级及下级字典数组中查找,有path路径
    return [self.carsArray valueForKeyPath:@"title"];
}

(8)为方便展示观看:

//隐藏状态栏
-(BOOL)prefersStatusBarHidden{
    return YES;
}

总结:

——难度在于字典转模型的地方,因为模型有2层级。

——增加了一个知识点,即显示组索引。用sectionIndexTitlesForTableView方法,返回值是一个数组,所以我们这里也用到了valueForKeyPath这个方法取得一个字符串组。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。