IOS开发UI进阶之UITableView一

来源:互联网 发布:人工智能会取代人类吗 编辑:程序博客网 时间:2024/04/29 05:14

一 UITableView

  • 什么是UITableView
    • 在iOS中要实现展示列表数据,最常用的做法就是使用UITableView
    • UITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳
  • UITableView的两种样式(Table View→Style)
    • UITableViewStylePlain(普通样式)
    • UITableViewStyleGrouped(分组样式)
  • 如何展示数据
    • UITableView需要一个数据源(dataSource)来显示数据
    • UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等
    • 凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源
  • tableView和数据源
    这里写图片描述

二 UITableView基本用法

  • 设置数据源
  self.tableView.dataSource = self;
  • 数据源遵守数据源协议
@interface ViewController () <UITableViewDataSource>
  • 实现数据源方法
// 1.返回有多少组数据- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return 1;}// 2.返回每组有多少行数据- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.wines.count;}// 3.返回每一行的内容(UITableViewCell类型)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

4.tablView的常见属性

//1. 修改tableView的行高    self.tableView.rowHeight = 100;    // 2.组头组尾的高    self.tableView.sectionHeaderHeight = 55;    self.tableView.sectionFooterHeight = 22;    // 3.设置整个tablView的头部/尾部视图    self.tableView.tableHeaderView = [[UISwitch alloc] init];    self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeInfoDark];    // 4.设置我们分割线颜色(clearColor相当于取消系统分割线)    //self.tableView.separatorColor = [UIColor clearColor];    // 5.设置分割线样式    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;    // 设置索引条内部文字颜色为不纯洁颜色    self.tableView.sectionIndexColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];    // 设置索引条背景颜色为纯洁颜色    self.tableView.sectionIndexBackgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
  • tableViewCell 的常见属性
// 设置cell右边样式    cell.accessoryType;    cell.accessoryView;// cell.accessoryView优先级 > accessoryType    // selectedBackgroundView设置选中背景优先级是比selectionStyle高    UIView *bg = [[UIView alloc] init];    bg.backgroundColor = [UIColor purpleColor];//    cell.selectedBackgroundView = bg;//    //UITableViewCellSelectionStyleBlue 在iOS7之后和Gray效果相同//    cell.selectionStyle = UITableViewCellSelectionStyleBlue;    // backgroundView它的优先级比backgroundColor高,并且这俩是并存    cell.backgroundView = bg;    cell.backgroundColor = [UIColor yellowColor];    cell.contentView;
  • tableView常用代理方法
// 当选中index行cell时候会调用- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath// 当取消选中cell时候调用- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath// 返回对应行的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath// 返回对应组的组头高度- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section// 返回对应组头试图- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

三 展示多组数据

  • 字典样式
@interface ViewController () <UITableViewDataSource>@property (nonatomic, strong) NSArray *carGroups; /**< carGroup模型数组 */@end
- (NSArray *)carGroups{    if (!_carGroups) {       NSArray *cars = @[[XMGCar carWithName:@"奔驰" Logo:@"m_2_100"],                   [XMGCar carWithName:@"宝马" Logo:@"m_3_100"],                          ]; XMGCarGroup *carGroup0 = [XMGCarGroup carGroupWithHeader:@"德系品牌" Footer:@"的新品牌高大上的footer" Cars:cars];NSArray *cars1 = @[[XMGCar carWithName:@"法拉利" Logo:@"m_91_100"],[XMGCar carWithName:@"兰博基尼" Logo:@"m_86_100"],[XMGCar carWithName:@"玛莎拉蒂" Logo:@"m_93_100"],                          ];XMGCarGroup *carGroup1 = [XMGCarGroup carGroupWithHeader:@"意大利系品牌" Footer:@"意大利的新品牌高大上的footer" Cars:cars1];NSArray *cars2 = @[[XMGCar carWithName:@"比亚迪" Logo:@"m_15_100"],                        ];XMGCarGroup *carGroup2 = [XMGCarGroup carGroupWithHeader:@"天系品牌" Footer:@"china的新品牌高大上的footer" Cars:cars2];        _carGroups = @[carGroup0, carGroup1, carGroup2];    }    return _carGroups;}
  • 字典转模型方法(XMGCarGroup)
+ (instancetype)carGroupWithDict:(NSDictionary *)dict{    XMGCarGroup *carGroup = [[XMGCarGroup alloc] init];    carGroup.header = dict[@"header"];    carGroup.footer = dict[@"footer"];    // 1.拿到字典数组    NSArray *dictCars = dict[@"cars"];    // 2.字典数组-> 模型数组    NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:dictCars.count];    for (NSDictionary *dictCar in dictCars) {        XMGCar *car = [XMGCar carWithDict:dictCar];        [arrayM addObject:car];    }    // 要求cars是car模型数组,而不是字典数组    carGroup.cars = [arrayM copy];    return carGroup;}
  • 组头组尾设置
// 返回组头文字:note:(如果是英文他会自动变成大写)- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{    XMGCarGroup *carGroup = self.carGroups[section];    return carGroup.header;}// 返回组尾文字- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{    XMGCarGroup *carGroup = self.carGroups[section];    return carGroup.footer;}
  • 复杂plist解析→数组转模型
// 懒加载#warning 当不展示数据时,先看!_carGroups的!是否写了,再看plist是否敲对- (NSArray *)carGroups{    if (!_carGroups) {        // 1.获取我们的plist文件路径        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"cars" ofType:@"plist"];        // 2.获取dict数组        NSArray *dictCarGroups = [NSArray arrayWithContentsOfFile:filePath];        // 3.将dict数组->模型数组        NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:dictCarGroups.count];        for (NSDictionary *dict in dictCarGroups) {            XMGCarGroup *carGroup = [XMGCarGroup carGroupWithDict:dict];            [arrayM addObject:carGroup];        }        // 4.赋值        _carGroups = [arrayM copy];        }    return _carGroups;}
  • 实现tableView样式
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{    return self.carGroups.count;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    XMGCarGroup *carGroup = self.carGroups[section];    return carGroup.cars.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    // 1.创建cell    UITableViewCell *cell = [[UITableViewCell alloc] init];    // 2.设置cell右边样式    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;    // 3.设置cell内部的数据    XMGCarGroup *carGroup = self.carGroups[indexPath.section];    XMGCar *car = carGroup.cars[indexPath.row];    cell.textLabel.text = car.name;    cell.imageView.image = [UIImage imageNamed:car.icon];    // 4.返回    return cell;}

三 展示单组数据

// 懒加载- (NSArray *)wines{    if (nil == _wines) {        // 1.        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"wine.plist" ofType:nil];        // 2.加载字典数组        NSArray *dictWines = [NSArray arrayWithContentsOfFile:filePath];        // 3.数组转字典        NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:dictWines.count];        for (NSDictionary *dict in dictWines) {            XMGWine *wine = [XMGWine wineWithDict:dict];            [arrayM addObject:wine];        }        _wines = [arrayM copy];    }    return _wines;}
  • Cell简介

    • UITableView的每一行都是一个UITableViewCell,
      • 通过dataSource的tableView:cellForRowAtIndexPath:方法来初始化每一行
    • UITableViewCell内部有个默认的子视图:contentView,
      • contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图
    • 辅助指示视图可以通过设置UITableViewCell的accessoryType来显示
      • 默认是UITableViewCellAccessoryNone(不显示辅助指示视图),其他值如下:
        这里写图片描述
  • UITableViewCell的contentView

    • contentView下默认有3个子视图
      • 2个是UILabel(通过UITableViewCell的textLabel和detailTextLabel属性访问)
      • 第3个是UIImageView(通过UITableViewCell的imageView属性访问)
    • UITableViewCellStyle属性
      • 作用决定这些子视图在contentView中的位置
        这里写图片描述

四 性能优化

  • 系统可以做到cell用到几个创建几个,存在问题就是重复创建cell
    • cell样式一样,地址不一样
  • 性能优化(缓存池)

    • 通过一个标识去缓存池中找可循环利用的cell
    • 如果缓存池中找不到可循环利用的cell,创建一个新的cell,给cell贴上标识
    • 给cell设置新的数据
  • cell的循环利用

    • 传统的写法

      /***  每当有一个cell要进入视野范围内,就会调用一次*/- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{static NSString *ID = @"wine";// 1.先去缓存池中查找可循环利用的cellUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];// 2.如果缓存池中没有可循环利用的cellif (!cell) {    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];}// 3.设置数据cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row];return cell;}
    • 新的写法(注册cell)

      NSString *ID = @"wine";- (void)viewDidLoad {[super viewDidLoad];// 注册某个重用标识 对应的 Cell类型[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{// 1.先去缓存池中查找可循环利用的cellUITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];// 2.设置数据cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row];return cell;}

五 索引条

  • 做法一:

    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{return [self.carGroups valueForKeyPath:@"title"];}
  • 做法二:

    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{NSMutableArray *arrayM = [NSMutableArray array];for (XMGCarGroup *carGroup in self.carGroups) {[arrayM addObject:carGroup.title];} return arrayM;}
0 0
原创粉丝点击