UITableView示例-LOL英雄列表
运行效果
CZHero.h
// // CZHero.h // 04-UITableView示例-加载plist文件 // // Created by ChenQianPing on 16/1/21. // Copyright © 2016年 chenqp. All rights reserved. // #import <Foundation/Foundation.h> @interface CZHero : NSObject // 头像图片 @property (nonatomic,copy) NSString *icon; // 英雄简介 @property (nonatomic,copy) NSString *intro; // 英雄名称 @property (nonatomic,copy) NSString *name; - (instancetype)initWithDict:(NSDictionary *)dict; + (instancetype)heroWithDict:(NSDictionary *)dict; @end
CZHero.m
// // CZHero.m // 04-UITableView示例-加载plist文件 // // Created by ChenQianPing on 16/1/21. // Copyright © 2016年 chenqp. All rights reserved. // #import "CZHero.h" @implementation CZHero - (instancetype)initWithDict:(NSDictionary *)dict { if (self = [super init]){ [self setValuesForKeysWithDictionary:dict]; } return self; } + (instancetype)heroWithDict:(NSDictionary *)dict { return [[self alloc] initWithDict:dict]; } @end
ViewController.m
// // ViewController.m // 04-UITableView示例-加载plist文件 // // Created by ChenQianPing on 16/1/21. // Copyright © 2016年 chenqp. All rights reserved. // #import "ViewController.h" #import "CZHero.h" @interface ViewController () <UITableViewDataSource,UITableViewDelegate> // 保存英雄的集合 @property (nonatomic,strong)NSArray *heros; @property (weak, nonatomic) IBOutlet UITableView *tableView; @end @implementation ViewController #pragma mark - 代理方法 //- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath //{ // int rowNum = indexPath.row; // if(rowNum % 2 == 0){ // return 60; // } else { // return 120; // } // //} // 监听行被选中的代理方法 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // 获取当前被选中的这行的英雄的名称 CZHero *hero = self.heros[indexPath.row]; // NSLog(@"%ld", (long)indexPath.row); // 省去了繁琐的代理方法,原来的控件点击每个功能按钮调用方法 还得调用代理方法 要不然就是自己封装一下,现在好了 由一个控制器来管理 操作方便了些 而且每个功能键都很清晰,点击调用的方法都写在block回调中这样方便了很多不是吗? 而且将原来的两个控件合二为一。我们可以自行再次对其封装 使用会更加方便。 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"编辑英雄" message:hero.name preferredStyle:UIAlertControllerStyleAlert]; __weak typeof(alertController) weakAlert = alertController; [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { NSLog(@"点击取消"); }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { NSLog(@"点击了确定按钮--%@-%@", [weakAlert.textFields.firstObject text], [weakAlert.textFields.lastObject text]); // 更新数据 // 1.获取用户文本框中输入的内容 NSString *name = [weakAlert.textFields.firstObject text]; // 2.找到对应的英雄模型 // CZHero *hero = self.heros[indexPath.row]; // 3.修改英雄模型的name hero.name = name; // 4.刷新TableView(重新刷新数据的意思就是重新调用UITableView的数据源对象中的那些数据源方法) // reloadData表示刷新整个tableView // [self.tableView reloadData]; // 局部刷新,刷新指定的行 // 创建一个行对象 NSIndexPath *idxPath = [NSIndexPath indexPathForRow:indexPath.row inSection:0]; [self.tableView reloadRowsAtIndexPaths:@[idxPath] withRowAnimation:UITableViewRowAnimationLeft]; }]]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { NSLog(@"添加一个textField就会调用 这个block"); textField.text = hero.name; }]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { NSLog(@"添加一个textField就会调用 这个block"); textField.text = hero.intro; }]; // 由于它是一个控制器 直接modal出来就好了 [self presentViewController:alertController animated:YES completion:nil]; } #pragma mark - 懒加载数据 // 一般的数据,在从文件或数据库中读取后,会用到多次,这时候要养成懒加载数据的习惯,以提高程序的性能,其实你不使用懒加载,从使用者来说,如果数据量小,没什么影响,但如果数据量大,使用懒加载数据就有明显的优势了。 - (NSArray *)heros{ if (_heros == nil) { // 1.获得plist的全路径 NSString *path = [[NSBundle mainBundle] pathForResource:@"heros.plist" ofType:nil]; // 2.加载数组 NSArray *arraryDict = [NSArray arrayWithContentsOfFile:path]; // 3.将arraryDict里面的所有字典转成模型对象,放到新的数组中 NSMutableArray *arrayModels = [NSMutableArray array]; for (NSDictionary *dict in arraryDict) { // 3.1.创建模型对象 CZHero *model = [CZHero heroWithDict:dict]; // 3.2.添加模型对象到数组中 [arrayModels addObject:model]; } // 4.赋值 _heros = arrayModels; } return _heros; } #pragma mark - 数据源方法 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // NSLog(@"numberOfSectionsInTableView"); return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // NSLog(@"numberOfRowsInSection--组索引:%ld",(long)section); return self.heros.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // NSLog(@"cellForRowAtIndexPath---组索引:%ld,行索引:%ld",(long)indexPath.section,(long)indexPath.row); // 1.获取模型数据 CZHero *model = self.heros[indexPath.row]; // 2. 创建单元格 // UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil]; // 因为每次都创建一个单元格效率比较低,所以要对单元格进行重用 // 单元格重用的基本思路就是: // 1> 在创建单元格的时候指定一个"重用ID" // 2> 当需要一个新的单元格的时候,先去"缓存池"中根据"重用ID"是否有可用的单元格 // ** 如果有,则直接从缓存池中取出这个单元格,进行使用(修改这个单元格中显示的的数据样式) // ** 如果没有需要的单元格,此时只能重新创建一个单元格了. // 声明一个重用ID // 英雄单元格重用ID static NSString *ID = @"hero_cell"; // 根据这个重用ID去"缓存池"中查找对应的Cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 判断,如果没有手到可用的cell,那么重新创建一个 if (cell == nil){ // NSLog(@"=========组索引:%ld,行索引:%ld",(long)indexPath.section,(long)indexPath.row); // 创建一个新的单元格 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } // 3. 把模型数据设置给单元格 // 设置英雄图标 cell.imageView.image = [UIImage imageNamed:model.icon]; // 设置英雄姓名 cell.textLabel.text = model.name; // 设置英雄描述 cell.detailTextLabel.text = model.intro; // 要在单元格的最右边显示一个小箭头,所以要设置单元格对象的某个属性 // 通常accessoryType提供的类型不能满足时,才会使用自定义控件 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; // 可以自定义单元格右边的accessory // cell.accessoryView = [[UISwitch alloc] init]; // 输出当前单元格的地址 NSLog(@"%p-----行索引:%d",cell,indexPath.row); // 4.返回单元格 return cell; } // 隐藏顶部状态栏 - (BOOL)prefersStatusBarHidden { return YES; } - (void)viewDidLoad { [super viewDidLoad]; // 如果每行的行高是一样的,那么通过rowHeight统一设置行高效率更高 self.tableView.rowHeight = 60; // // 设置分割线的颜色 // self.tableView.separatorColor = [UIColor redColor]; // 对于行的行高不一样的情况,无法通过tableView.rowHeight来实现 // 此时,只能通过一个代理方法来实现。 } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
时间: 2024-10-02 18:37:05