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

一. 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 包含的控件有细微差别

三. 重用机制

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

四. 方法们
- ( 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
{
   
}














  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值