UI一揽子计划 9 (UITableView 、UITableView 、重用机制)

本文详细介绍了UITableView的工作机制,包括数据展示、代理方法、重用机制等,并通过实例展示了如何实现UITableView的布局和数据展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. UITableView

UITableView继承自UIScrollView,所以可以滚动
表视图的每⼀一条数据都是显示在UITableViewCell对象中
表视图可以分区显⽰示数据,每个分区称为⼀一个section,每⼀一⾏行称为 row,编号都是从0开始

两个代理 :
@interface  UIViewController<UITableViewDataSource,UITableViewDelegate>
这两个方法必须实现
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
 
二. UITableView

UITableView中每⼀一个单元格,被称为⼀一个cell
(UITableViewCell)。 系统预置了4种(枚举)样式的cell。 不同样式的cell包含的控件有细微差别

三. 重用机制

UITableViewmutableSet来实现重⽤用功能
出屏幕的cell会被添加到mutableSet中,进⼊入屏幕的cell,先从set中 获取,如果获取不到,才创建⼀一个cell。在cell显⽰示之前,给cell赋上 相应的内容。
cellreuseIdentifier是重用的关键。

四. 方法们
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; //分区数
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; //分区头标题
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; //右侧竖排索引

// 下面四个方法用来设置单元块的头和尾的高度和View
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;

// 单元格的高度及选中
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
五. MVC模式的实现
(详见UITableView0004)
UITableView0001
     // 创建并初始化一个UITableView
    /*
     UITableViewStylePlain  
不分区  表头标题可以固定到该分区的最后一行画出的时候改变
     UITableViewStyleGrouped 
分区  标题显示在
     */

   
UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds  style:(UITableViewStylePlain)];
// 设置重要属性
   
// 一个数据源  一个代理的属性
    tableView.
dataSource = self;
    tableView.
delegate = self;
   
   
// 设置表头和表尾
 
// 这个是整个tableView的表头和表尾
   
UIView *headView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 100)];  // 最好设置375
    headView.
backgroundColor = [UIColor greenColor];
    tableView.
tableHeaderView = headView;
    [headView
release];
   
   
UIView *footView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    footView.
backgroundColor = [UIColor redColor];
    tableView.
tableFooterView = footView;
    [footView
release];
   
    [
self.view addSubview:tableView];

}

#pragma mark ---- datasource  两个必须实现的方法
// 返回每个分区有多少行
- (
NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   
return 15;
}
~~~~~返回有多少个分区
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   return 3;
}

~~~~返回每一行的样式

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   
// 创建一个UITableViewCell 并返回
   
// 四种样式  默认    reuseIdentifier 标识符
   
/*
     //
详情标题
     cell.detailTextLabel.text = @"df";
     cell.textLabel.text = @"haha ";
     UITableViewCellStyleDefault  
子标题不显示
     UITableViewCellStyleSubtitle 
子标题在下面
     UITableViewCellStyleValue1
子标题在右面
     UITableViewCellStyleValue2
子标题压缩了  有图片不用这个
    
    */
  UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:@"CKCell"];
    cell.
imageView.image = [UIImage imageNamed:@"faye1"];
    cell.
detailTextLabel.text = @"df";
    cell.
textLabel.text = @"haha ";
   
// cell 右面按钮的样式  (四种样式      箭头  圈和箭头)
    cell.
accessoryType = UITableViewCellAccessoryDetailButton;
   
return [cell autorelease];
   
// 不用 release ?????????????
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
   
NSLog(@"%ld", section);
   
// 返回 每个分区 表头的标题信息
  
// return @"A";
   
if (section == 0) {
       
return @"a";
    }
else if (section == 1) {
       
return @"b";
    } 
else {
       
return @"c";
    }
}
 (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
   
// tableView 分区索引的标题们
   
return @[@"a",@"b",@"c"];
}
- (
void)didReceiveMemoryWarning {
    [
super didReceiveMemoryWarning];
   
// Dispose of any resources that can be recreated.
}
~~~~~~~设置每个分区的表头跟表尾  这个使用代理方法来实现的
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
   
UIView *headView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 5)]autorelease];  // 最好设置375
    headView.
backgroundColor = [UIColor orangeColor];
   
return  headView;

}

~~~~~返回每个分区的表头高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
   
return 50;
}

~~~~~表尾如上.......
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
   
return 50;
}
- (
UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
   
UIView *footView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 375, 5)];
    footView.
backgroundColor = [UIColor grayColor];
    return  [footView autorelease];  
}
~~~~~~~~恶心版Plus
// 返回的是每个cell 的高度
- (
CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
   
return 100;
}

 上午小结
 
 *  1.
创建的时候有两种样式
    2.
有两个代理  datasourse(两个方法必须执行必须实现的
                                ->1.
分区有多少行,
                                ->2.
每行都是什么样式的cell
                                <-
有几个分区
                                <-
表头表尾的标题
                            )
                  UItableDelegate (//cell 的高度)   要释放

UITableView0002
- (void)dealloc
{
    [
_dataArray release];
    [
super dealloc];
}

- (
void)viewDidLoad {
    [
super viewDidLoad];
    [
self addTableView];
   
// Do any additional setup after loading the view.
}

~~~~~~创建假数据
- (void)setUpDate
{
   
self.dataArray = @[@"思聪",@"小芳",@"",@"",@""];
}

// 创建tableView
- (
void)addTableView
{
   
UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:(UITableViewStylePlain)];
   
// 设置代理    数据源
    tableView.
delegate = self;
    tableView.
dataSource = self;
    [
self.view addSubview:tableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    [
self setUpDate];
  
// NSLog(@"我是第%ld分区的", section);
   
// 返回每个分区有多少行
   
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
#pragma mark ---以后禁止这么写
   
// NSIndexPath有行和分区的属性
//    NSLog(@"我是%ld分区的%ld", indexPath.section, indexPath.row);
//    UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:@"cell"];
   
// 利用 行数 indexpath.row 的变化  按照下标  动态的取出数据
//    cell.textLabel.text = self.dataArray[indexPath.row];
//    return cell;
   
   
   
#pragma mark ---重用机制
    /**
     * 
重用机制 
            1.
首先要知道屏幕显示几条数据 比如 5条数据
    
            2.
当向上滑的时候,有两个创建的选择 先要去集合里面找, 找不到就创建一个(第一次找的时候肯定没有,需要创建一个的)
    
            3.
当第一个cell 完全划出屏幕的时候 这时候该cell 变成未显示状态,然后扔进集合里面.
    
            4.
当下面再需要新出来的一个的时候,先去集合中找未显示状态的,有旧直接用,没有就去创建.
    
            5.
如此循环 终成正果
    
    
~~~~~~~~
可变集合中刚开始显示几个 集合中就有几个(只不过是显示状态的 最多这个集合中有几个?   显示的数量 + 1 .
     */

   

#pragma mark ---以后这么写
   
   
   
// 先写一个标识符  加上static 就只初始化一次
  
static NSString *identifier = @"JJCell";
   
// 去集合里面取找  有的话就使用
   
   
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
   
~~~~~~下面进行判断 如果没有就创建
    if (cell == nil) {
        cell = [[[
UITableViewCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifier]autorelease];
    }
   
~~~~~~对取出来的或者新创建的进行赋值 (即改名字)
   
    cell.
textLabel.text = self.dataArray[indexPath.row];
   
return cell;
}

UITableView0003
- (void)setUpData
{
   
NSArray *groupD = [NSArray arrayWithObjects:
                      
@"尚亚雷",
                      
@"李永乐", nil];
   
NSArray *groupC = [NSArray arrayWithObjects:
                      
@"李云飞",
                      
@"莫亮萍", nil];
   
NSArray *groupM = [NSArray arrayWithObjects:
                      
@"陈文博",
                      
@"孙永飞",
                      
@"王东旭", nil];
   
NSArray *groupN = [NSArray arrayWithObjects:
                      
@"闫亚军",
                      
@"仝兴伟",
                      
@"代秋田",
                      
@"何亚楠",
                      
@"张宏宇",
                      
@"朱海明",
                      
@"杨松", nil];
   
NSArray *groupE = [NSArray arrayWithObjects:
                      
@"于慧霞",
                      
@"庞仕山",
                      
@"陈岩岩",
                      
@"柳中帅",
                      
@"冯贵宾",
                      
@"杨秘",
                      
@"杨雪蕾",
                      
@"王强",
                      
@"薛石磊",
                      
@"王增双",
                      
@"裴小芳",
                      
@"毛军军",nil];
   
NSArray *groupK= [NSArray arrayWithObjects:
                     
@"张国文",
                     
@"张莹莹",
                     
@"郑明",
                     
@"张莹莹",
                     
@"崔锴",
                     
@"蒲元凯",
                     
@"顾成辉",
                     
@"王向明",
                     
@"冯振玲",
                     
@"陈健健",
                     
@"夏炎",
                     
@"王昊",
                     
@"武自健",nil];
   
NSArray *groupA = [NSArray arrayWithObjects:
                      
@"卢奕霖",
                      
@"王艺拓",
                      
@"李雨",
                      
@"刘新林",
                      
@"田菲菲",
                      
@"李琳冰",
                      
@"王岩",
                      
@"郭杰",
                      
@"杨淋淇",
                      
@"肖扬",
                      
@"黎一良",
                      
@"谷浩",
                      
@"孙昊坤",nil];
   
NSArray *groupZ = [NSArray arrayWithObjects:
                      
@"赵枫俊",
                      
@"张明军",
                      
@"刘迪",
                      
@"聂银龙",
                      
@"张博",
                      
@"王珂", nil];
   
   
self.dataDic = @{@"A":groupA, @"Z":groupZ, @"C":groupC, @"D":groupD, @"K":groupK, @"E":groupE, @"M":groupM, @"N":groupN};
   
   
// 5. 取出所有的KEYs 进行排序
   
   
NSArray *keys = [self.dataDic allKeys];
   
self.sortKeysArray = [keys sortedArrayUsingSelector:@selector(compare:)];
   
NSLog(@"%@", self.sortKeysArray);
   
   
}

- (
void)addTableView
{
   
// 1.
   
UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:(UITableViewStylePlain)];
   
// 2.代理
    tableView.
delegate = self;
    tableView.
dataSource = self;
    [
self.view addSubview:tableView];
    [tableView
release];
}
// 3. 多少行
- (
NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
   
   
// 把对应的数组取出来
   
NSString *key = self.sortKeysArray[section];
   
NSArray *values = self.dataDic[key];
   
   
return values.count;
}


- (
UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   
static NSString *identifier = @"JJCell";
   
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
   
if (cell == nil) {
        cell = [[[
UITableViewCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifier]autorelease];
    }
   
   
// 6.
   
// 显示数据      利用indexPath.section 分区 取出key
   
NSString *key = self.sortKeysArray[indexPath.section];
   
// 利用 key 值来取出 每一个数组
   
NSArray *values = self.dataDic[key];
   
// 利用 indexPath.row 每个分区的行数 取出数组中的字符串
    cell.
textLabel.text = [values objectAtIndex:indexPath.row];
   
return cell;
}

// 4. 返回分区数

-(
NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   
// 有多少键值对就返回多少
   
return self.dataDic.count;
}
// 7. 现加表头标题
- (
NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
   
// 用分区取出key
   
NSString *key = self.sortKeysArray[section];
   
return key;
}
// 8. 右面的点击的 contentOFFSet 偏移量
- (
NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
   
return  self.sortKeysArray;
}

UITableView0004

UITableView.m文件
// 1. 处理数据
- (
void)setUpData
{
   
// 读取文件夹中的数据文件plist文件
       
// 工程的目录  [NSBundle mainBundle]
   
NSString *path = [[NSBundle mainBundle] pathForResource:@"TableViewPlist" ofType:@"plist"];
   
// 将文件中的数据拿出来 放到字典里面
   
NSDictionary *plistDic = [NSDictionary dictionaryWithContentsOfFile:path];
// 我从定义属性字典过来
   
// 循环外面初始化这个大字典
   
self.dataDic = [NSMutableDictionary dictionary];
// 我是从CellModel过来的.
    // 遍历字典
   
// 取出所有的Key
   
NSArray *keys = [plistDic allKeys];
   
for (int i = 0; i < keys.count; i++) {
       
// 先把Key 取出来
       
NSString *key = keys[i];
       
// 取出每个key 对应的数组
       
NSArray *values =[plistDic objectForKey:key];
       
// 我从下面的KVC跳上来的
       
// 创建数组 保存赋值完成的model
       
       
NSMutableArray *tempArray = [NSMutableArray array];
       
// 继续遍历每个数组
       
for (NSDictionary *dic in values) {
           
           
// 一个字典对应一个model
           
// 创建model
           
CellModel *model = [[CellModel alloc]init];
           
// model 进行赋值
           
// 1. 一般赋值 一般不这么写 属性多了的话 太麻烦
           
//model.title = [dic objectForKey:@"title"];
           
//(KVC)赋值  一般都这么写
            [model
setValuesForKeysWithDictionary:dic];
           
// model 加到临时的可变数组里
            [tempArray
addObject:model];
            [model
release];
        }
        [
self.dataDic setObject:tempArray forKey:key];
    }
   
NSLog(@"%@", self.dataDic);
}


- (
void)addTableView
{
   
UITableView *tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:(UITableViewStyleGrouped)];
    tableView.
delegate = self;
    tableView.
dataSource = self;
    [
self.view addSubview:tableView];
    [tableView
release];
}

- (
NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   
   
// 取出所有key
   
NSArray *keys = [self.dataDic allKeys];
   
NSString *key = keys[section];
   
NSArray *values = [self.dataDic objectForKey:key];
   
return values.count;
}


- (
UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   
NSString *identifier = @"JJcell";
   
UITableViewCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identifier];
   
if (cell == nil) {
         cell = [[
UITableViewCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifier];
    }
   
   
// 取出所有key
   
NSArray *keys = [self.dataDic allKeys];
   
NSString *key = keys[indexPath.section];
   
NSArray *values = [self.dataDic objectForKey:key];
   
CellModel *model = values[indexPath.row];
    cell.
textLabel.text = model.title;
    cell.
imageView.image =[UIImage imageNamed:model.imageName];
   
return cell;

}
- (
NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   
return self.dataDic.count;
}
- (
void)didReceiveMemoryWarning {
    [
super didReceiveMemoryWarning];
   
// Dispose of any resources that can be recreated.
}
- (
void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   
NSLog(@"%ld 分区  %ld ", indexPath.section, indexPath.row);
}

CellModel.m文件
- (void)dealloc
{
    [
_title release];
    [
_imageName release];
    [
super dealloc];
}
// KVC 赋值保护  如果配对错了就会 抛出异常 可以直接打印出错的key  否则直接崩溃
对它进行空实现
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
   
}














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值