【iOS开发之旅】UITableView示例-LOL英雄列表

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-12-11 21:08:12

【iOS开发之旅】UITableView示例-LOL英雄列表的相关文章

iOS开发UI篇—UITableview控件基本使

iOS开发UI篇—UITableview控件基本使用 一.一个简单的英雄展示程序 NJHero.h文件代码(字典转模型) #import <Foundation/Foundation.h> @interface NJHero : NSObject /** * 头像 */ @property (nonatomic, copy) NSString *icon; /** * 名称 */ @property (nonatomic, copy) NSString *name; /** * 描述 */ @

iOS开发UI篇—UITableview控件使用小结

iOS开发UI篇—UITableview控件使用小结 一.UITableview的使用步骤 UITableview的使用就只有简单的三个步骤: 1.告诉一共有多少组数据 方法:- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; 2.告诉每组一共有多少行 方法:- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSIntege

学习IOS开发UI篇--UITableView/数据模型嵌套/UITableViewCell/Cell的重用

1.UITableView ================================================== UITableView有两种格式:group和plain 2.UITableView如何展示数据 ================================================== UITableView需要一个数据源(dataSource)来显示数据 凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的

IOS开发中的UITableView与UITableViewCell

UITableView用来以表格的形式显示数据.关于UITableView,我们应该注意: (1)UITableView用来显示表格的可见部分,UITableViewCell用来显示表格的一行. (2)UITableView并不负责存储表格中的数据,而是仅仅存储足够的数据使得可以画出当前可见部分. (3)UITableView从UITableViewDelegate协议获取配置信息,从UITableViewDataSource协议获得数据信息. (4)所有的UITableView实现时实际上只有

IOS开发UI篇--UITableView的自定义布局==xib布局

利用Xib进行实现 应用场景:像团购网站的列表数据显示,新闻列表显示等(由于该类的显示的数据单元格内容格式相同) (1)主控制器文件,在文件中实现了自己自定义的代理,加载数据, 1 #import "SLViewController.h" 2 #import "SLTgDatas.h" 3 #import "SLTableViewCell.h" 4 #import "SLFooterView.h" 5 #import &quo

IOS开发UI篇--UITableView的自定义布局==纯代码布局

UITableView中除了利用系统的UItableViewCell不能完成需求进行布局时,还可以进行自定义布局: 自定义布局分为两类:(1)利用代码进行创建 (2)利用xib进行实现: 下面对利用代码进行创建分析: 应用场景:像微博,等列表数据展示(由于微博的每个单元格的数据大小不一致,所以得计算每个单元格的大小) 分析:前提是获取列表数据,然后建立每个单元格的模型(建立单元格模型应继承UITableViewCell)复写 - (id)initWithStyle:(UITableViewCel

iOS开发之旅之UIViewController解析

就iOS开发来说,UIViewController就最核心的类型之一.而iOS的整个UI开发的核心思想也是MVC的架构,从UIViewController的命名就可以看出它在MVC中所扮演的角色,那就是Controller啦. Controller作为整个UI视图的控制器,对于用户的输入做出逻辑处理,例如用户点击某个按钮应该执行什么操作等:View角色只负责显示视图,view的这部分就是我们在nib或者storyboard设计的UI了.Model也就是我们的数据模型,例如从Core data中加

iOS开发UI篇—UITableView全面解析

概述 在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是UITableView.当然它的广泛使用自然离不开它强大的功能,今天这篇文章将针对UITableView重点展开讨论.今天的主要内容包括: 基本介绍 数据源 代理 性能优化 UITableViewCell 常用操作 UITableViewController MVC模式 基本介绍 UITableView有两种风格:UITableViewSt

大钟的ios开发之旅(2)————简单说说ios中ARC与非ARC模式下的property的变量修饰词

/******************************************************************************************** * author:[email protected]大钟 * E-mail:[email protected] *site:http://www.idealpwr.com/ *深圳市动力思维科技发展有限公司 * http://blog.csdn.net/conowen * 注:本文为原创,仅作为学习交流使用,转