zoukankan      html  css  js  c++  java
  • UITableView

    一、UITableViewController类,继承自ViewController。UITableView继承自UIScrollView。

    1、UITableViewController极大的简化了创建 UITableView的过程,减少甚至消除了直接处理表格实例所需的重复步骤。

    2、UITableViewController负责处理表格式图布局的繁琐细节,可便捷的创建表格,为委托和数据源添加本地TableView实例并提供自动化表格协议支持。

    二 、实现表格的3个关键元素:布局、数据(数据源)、交互(实现委托)。

    1、布局    

         UITableViewStyle: UITableViewStylePlain                      // regular table view

                                    UITableViewStyleGrouped                 // preferences style table view

         注意:如果继承的UITableViewController类,那么在viewDidLoad方法中,千万不要加上[self.view addSubview:self.tableView];不然会崩溃。貌似是因为UITableViewController中已经有一个tableView变量,已经把这个tableView加进去了。

    2、指定数据源

        数据源负责联系路径和具体的UITableViewCell实例,并根据需要返回单元格。

        索引路径: 是NSIndex的对象,描述通过数据树到达特定节点的路径,即它们的分段、行。有两个属性:section、row

                      创建:           

        重用机制:当单元格因滚屏而脱离表格可见区时,表格可以将其缓存到重用队列中。

                      用法:我们可标记单元格以备重用,然后根据需要从该队列中提取。

                      在分配新单元格时,必须检查重用单元格是否可用。如果表格对dequeueReusableCellWithIndentifier:的请求返回nil,那么就需  要分配一个新的单元格。  

                      如果该方法返回一个单元格,可以使用对当前行和分段索引有意义的信息更新这个单元格,但不需要添加此单元格到重用队列。系统会为你处理所有细节。

                      目的:节省内存,更快、更便捷的提供单元格内容,特别是在用户滚动一个长列表时。

                      注意:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier  forIndexPath:indexPath];
    ...
    return cell
    }

    这段代码是默认自带的代码,我们一般会在下面接着写

    if(!cell){         cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];     }
    但是,这样运行的时候是会崩溃的,加断点发觉是在 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 这句话崩溃的。这是为什么了?
    跟踪进去发觉这个方法有个标注:NS_AVAILABLE_IOS(6_0);也就是说他只能在6.0以上的版本运行。换成另一个方法
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];就可以了。至于新方法怎么用,可参考这篇帖子:http://bbs.csdn.net/topics/390330467上面有这两个方法的解释。

              

     三、单元格

     1、单元格类型

         共有4种:UITableViewCellStyleDefault、UITableViewCellStyleSubtitle、UITableViewCellStyleValue1、UITableViewCellStyleValue2

         各个效果: 

        测试代码:

     1 //返回在某indexPath处的cell
     2 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
     3 {
     4     //尝试从重用队列中取出一个cell,如果返回nil,就要重新创建一个
     5 //    static NSString *CellIdentifier = @"BaseCell";
     6 //    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     7 //    if(!cell)
     8 //    {
     9 //        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    10 //    }
    11 //    cell.textLabel.text = [[UIFont familyNames] objectAtIndex:indexPath.row];
    12     
    13     UITableViewCellStyle style;
    14     NSString *cellIndetifier;
    15     switch (indexPath.row%4) {
    16         case 0:
    17             style = UITableViewCellStyleDefault;
    18             cellIndetifier = @"default";
    19             break;
    20         case 1:
    21             style = UITableViewCellStyleSubtitle;
    22             cellIndetifier = @"Subtitle";
    23             break;
    24         case 2:
    25             style = UITableViewCellStyleValue1;
    26             cellIndetifier = @"Value1";
    27             break;
    28         case 3:
    29             style = UITableViewCellStyleValue2;
    30             cellIndetifier = @"Value2";
    31             break;
    32     }
    33     
    34     UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIndetifier];
    35     if(!cell){
    36         cell = [[UITableViewCell alloc]initWithStyle:style reuseIdentifier:cellIndetifier];
    37     }
    38     
    39     if(indexPath.row>3){
    40         cell.imageView.image = [UIImage imageNamed:@"0.png"];
    41     }
    42     cell.textLabel.text = cellIndetifier;
    43     cell.detailTextLabel.text = @"subtitle";
    44     return cell;
    45 }
    View Code

    一个现象,如果一致滑动view,再滑上去,会发现前3个cell中也有图片了。思考这个现象发生的原因?

          当前4个cell退出当前屏幕时,这四个cell被放入了重用队列,在向下滑动的过程中,系统不断的从重用队列中取出cell,然后画图、修改text。当我们再滑上去的时候,重用队列里的cell都已经被贴了图,而我们没有并没有对这些图片进行处理,所以这些图片还是会显示在cell中。

          如果想让前3行一直不显示图片,也很简单,按照上面的分析,只需要把图片移除即可。加上代码

    if(indexPath.row <= 3){
            cell.imageView.image = nil;
    }

    2、单元格颜色交替

    3、自定义单元格

        网上很多教程都是用xib实现的,现在我们尝试用代码实现。

       新建两个类:新建MyCell类,继承自UITableViewCell,用来构造自己的cell;

                        新建MyCellContent类,继承自 NSObject,作为数据源,用来往我们的cell中填充数据。效果如下:

     

    4、移除单元格选中时的高亮

        单元格选中后有三种状态:UITableViewCellSelectionStyleNone(选中后没有任何颜色高亮),

        UITableViewCellSelectionStyleBlue(蓝色)     UITableViewCellSelectionStyleGray(灰色)

    两种方法:

    a、选中后不会有任何颜色变化,不推荐。  

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    b、允许单元格高亮显示,但是在交互完成之后移除高亮显示

        实现原理:在点击响应tableView:didSelectRowAtIndexPath:中,延时几秒后,调用deselectRowAtIndexPath:取消选中状态。

    //选中indexPath处的这一行,点击响应
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"row is %d",indexPath.row);
        self.navigationItem.title =  [[UIFont familyNames]objectAtIndex:indexPath.row];
        //[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
        [self performSelector:@selector(didSelectColorGone:) withObject:nil afterDelay:0.5f];
    }
    
    -(void)didSelectColorGone:(id)sender
    {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];//得到选中行的indexPath
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];//取消选中那一行
    }

    这里之所以用performSelector:方法间接调用,而不直接调用didSelectColorGone:方法,是因为用performSelector可以设置延时。

    5、一些特殊的单元格控件

    a、勾选    b、展开配件(蓝色的或灰色的朝右的小v型箭头)

    6、显示删除控件

    效果:图中的红色圆形标记以及右边的delete按钮。

    删除单元格设置:[self.tableViewsetEditing:YESanimated:YES];//设置为可编辑的

    实现的委托方法:

    // Override to support editing the table view.
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            NSLog(@"commitEditingStyle StyleDelete called!");
            // Delete the row from the data source
           // [self.tableView deleteRowsAtIndexPaths:indexPath withRowAnimation:UITableViewRowAnimationFade];
            [self updateItemAtIndexPath:indexPath withString:nil];
        }   
        else if (editingStyle == UITableViewCellEditingStyleInsert) {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }   
    }

    自己实现的删除方法:

    - (void) updateItemAtIndexPath: (NSIndexPath *) indexPath withString: (NSString *) string
    {
        // You cannot insert a nil item. Passing nil is a delete request.
        NSLog(@"updateItemAtIndexPath called");
        if (!string)
            [self.arry removeObjectAtIndex:indexPath.row];
        else
            [self.arry insertObject:string atIndex:indexPath.row];
        
        [self.tableView reloadData];
    }

    这里有个问题,我删除的明明是0000,结果后来实际删除的是4444,考虑应该是删除方法写的有问题。

        

  • 相关阅读:
    Cygwin 与 MinGW/MSYS/MSYS2,如何选择?甚至还有GNU utilities for Win32
    MinGW和MSYS项目是在一起的(翻译官网)
    库存限购
    ElasticSearch指南
    Windows系统的Jenkins持续集成环境
    JavaScript 框架
    Istio Service Mash管理微服务
    LinkedIn微服务框架rest.li
    Istio微服务架构初试
    github
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/3171902.html
Copyright © 2011-2022 走看看