zoukankan      html  css  js  c++  java
  • 【转】iOS6 之后的tableView的改动

    关于UITableView在ios6.0中的新用法  

    2013-10-11 13:48:58|  分类: iphone开发 |  标签:utableview  ios6  storyboard  |举报|字号 订阅

     
     

    近来经常看到朋友在使用最新的iOS SDK 6.0版本的UITabelView的时候,会出现以下的错误:

    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

    这个是什么错误呢?我们首先从字面上理解它,“must register a nib or a class for the identifier or connect a prototype cell in a storyboard”,这是说标记为Cell的UITableViewCell不能出列,你必须为这个Cell注册一个Class或从storyboard连接一个Cell(英文水平不怎么样,将就一下)。OK,我们到这个方法的文档里去一探究竟。

    我们看这个方法的注释 

    NS_AVAILABLE_IOS(6_0);

    // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered

    1  这是一个6.0才能使用的方法。

    2  获得一个Cell,假设标记的这个Cell已经被注册。

    我们再往下看,下面还有两个配套的方法:

    1. <span style="font-size:18px;">// Beginning in iOS 6, clients can register a nib or class for each cell.  
    2. // If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.  
    3. // Instances returned from the new dequeue method will also be properly sized when they are returned.  
    4. - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(5_0);  
    5. - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);</span>  

    我们先看他的注释:

    // Beginning in iOS 6, clients can register a nib or class for each cell.

    // If all reuse identifiers are registered, use the newer -dequeueReusableCellWithIdentifier:forIndexPath: to guarantee that a cell instance is returned.

    从IOS6开始,客户端可以为每一个cell注册nib或class

    如果所有的重用标记都被注册了,就可以使用新方法 -dequeueReusableCellWithIdentifier:forIndexPath:来获得一个cell实例。

    意即说如果要使用新方法 -dequeueReusableCellWithIdentifier:forIndexPath:就必须使用配套的

    - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier 或者 - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier这个方法。

    我们之前为什么会出现那样的错误,现在应该有点眉目了。出错的情况如下:

    1  编译的设备的系统低于6.0版本

    2  未使用配套的注册方法

     

    下面我来演示一下使用新方法来生成一个tableview

    1  新建一个Single View Application.

    2  新建一个MXCustomCell子类。如图:


    3  现在项目结构如下:


    4  打开ViewController.h,添加UITableViewDatasource,UITableViewDelegate协议。如图:


    5 打开ViewController.m,导入MXCustomCell.h,并声明一个CellIdentifier,如下:


    7 声明一个UITableView属性:

    @property (retain,nonatomic) UITableView *notNib_tableView;

    8  在viewDidLoad方法里添加下列语句:

    1. <span style="font-size:18px;">    self.notNib_tableView = [[UITableView alloc] initWithFrame:self.view.frame  
    2.                                                          style:UITableViewStyleGrouped];  
    3.       
    4.     //下面的这个方法如果使用之前的调用方法dequeueReusableCellWithIdentifier:forIndexPath: 则不用写  
    5.     [self.notNib_tableView registerClass:[MXCustomCell class] forCellReuseIdentifier:CellIdentifier];  
    6.     self.notNib_tableView.dataSource = self;  
    7.     self.notNib_tableView.delegate = self;  
    8.     [self.view addSubview:self.notNib_tableView];  
    9. </span>  

    9  下面添加UITableView的delegate的实现方法和datasource的实现方法:
    1. <span style="font-size:18px;">#pragma mark - tableView datasource  
    2. -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {  
    3.     return 1;  
    4. }  
    5.   
    6. -(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {  
    7.     return 5;  
    8. }  
    9.   
    10. -(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
    11.     //6.0之前的用法  
    12.     /* 
    13.     static NSString *CellIdentifier = @"Cell"; 
    14.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    15.      
    16.     if (cell == nil) { 
    17.         cell.textLabel.text = [NSString stringWithFormat:@"5.0方法 %d", indexPath.row]; 
    18.     }*/  
    19.       
    20.     //注意看这里,之前的老方法是dequeueReusableCellWithIdentifier: 没有后面的forIndexPath参数  
    21.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier  
    22.                                                             forIndexPath:indexPath];  
    23.     //这里做一些cell属性变换,如:  
    24.     cell.textLabel.text = [NSString stringWithFormat:@"6.0方法 %d", indexPath.row];  
    25.     return cell;  
    26. }  
    27. </span>  

    注意看,上面注释掉的6.0之前使用的方法和6.0之后的使用方法。

    10 OK,完成,我编译运行一下看看。


     

    OK,现在应该有点眉目了吧,所以说在我们使用新SDK的时候,如果出现上述错误,一般是以下的两种情况:

    1  编译的设备的系统版本低于6.0

    2  没有对dequeueReusableCellWithIdentifier: forIndexPath:使用配套的注册cell的方法

     

    PS:如果我不需要自定义Cell的时候怎么办呢,也方便,只需要

        [self.notNib_tableViewregisterClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];方法中的registerClass参数传一个[UITableViewCell class]过去就行了,这样就使用系统默认的UITableViewCell了。

  • 相关阅读:
    【LeetCode】Validate Binary Search Tree
    【LeetCode】Search in Rotated Sorted Array II(转)
    【LeetCode】Search in Rotated Sorted Array
    【LeetCode】Set Matrix Zeroes
    【LeetCode】Sqrt(x) (转载)
    【LeetCode】Integer to Roman
    贪心算法
    【LeetCode】Best Time to Buy and Sell Stock III
    【LeetCode】Best Time to Buy and Sell Stock II
    CentOS 6 上安装 pip、setuptools
  • 原文地址:https://www.cnblogs.com/lixiong-iOS/p/3613924.html
Copyright © 2011-2022 走看看