(十四)单组数据展示(字典转模型、模型初始化细节)
类似游戏助手,展示游戏资料。
可以通过程序进行网页抓取,从而生成要展示的plist。
Tip:在实现tableView的方法时,先写返回值再敲tableView可以过滤掉大部分方法,从而快速找到要实现的。
要在Cell中显示标题、内容、图片,应该设置样式为UITableViewCellStyleSubtitle。
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
然后通过textLabel、detailLabel、imageView三个cell的成员变量设置标题、详细、图片。
数据模型的建立:
每个模型有名称、描述、图标三个数据,定义两个初始化方法,一个构造方法,一个类方法。
@interface Hero : NSObject @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *icon; @property (nonatomic, copy) NSString *intro; + (instancetype)heroWithDict:(NSDictionary *)dict; - (instancetype)initWithDict:(NSDictionary *)dict; @end对于构造方法有固定的写法:
@implementation Hero + (instancetype)heroWithDict:(NSDictionary *)dict{ return [[self alloc] initWithDict:dict]; } - (instancetype)initWithDict:(NSDictionary *)dict{ if(self = [super init]){ [self setValuesForKeysWithDictionary:dict]; } return self; } @end对于类方法,先生成一个对象,然后调用对象方法。
对于对象方法,要先调用父类的构造方法,返回值再进行操作,注意if里面是一个等号,表示赋值,如果赋值失败则代表初始化失败。
这里因为是字典转模型,可以用setValuesForKeysWithDictionary方法快速将键值对转化为模型内数据(注意字典的key要和成员变量一一对应)。
模型的初始化:
首先建立模型数组:
@property (nonatomic, strong) NSArray *heros;
然后重写get方法进行懒加载:
1.利用bundle得到plist全路径并转化为字典数组。
2.建立Mutable临时数组,通过for-in遍历字典数组,将每一条字典数据加入到临时数组。
3.将临时数组赋值回成员变量数组并返回(如果已经赋值过则直接返回)。
- (NSArray *)heros{ if (_heros == nil) { NSString *path = [[NSBundle mainBundle] pathForResource:@"heros.plist" ofType:nil]; NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; NSMutableArray *heroArray = [NSMutableArray array]; for (NSDictionary *dict in dictArray) { Hero *hero = [Hero heroWithDict:dict]; [heroArray addObject:hero]; } _heros = heroArray;//不要忘了最后赋给成员变量。 } return _heros; }Tip:对于单组数据显示,可以不实现numberOfSectionsInTableView: 方法,默认是一组。
Tip:iOS7和以后的细节:分割线从label开始画,图片部分不画。
调整TableView的行高:(默认44)
方法一:self.tableView.rowHeight
方法二:使用方法来监听(代理,而不是dataSource)
@interface ViewController () <UITableViewDataSource,UITableViewDelegate>不要忘记了拖线设定代理或者代码设定。
然后实现方法:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 60; }方法二的好处:可以针对indexPath不同返回不同的高度。
总结:方法一用于每一行高度一致的情况,方法二用在行高不一致的情况。