• 【转】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了。

  • 相关阅读:
    大整数相加算法
    java中String和char的区别
    Git命令
    Dart随记
    用nodejs或者Chrome控制台的js对URI进行编码或解码
    Rust执行cmd或shell命令
    cargo expand用于查看被宏隐藏的代码
    Blocking waiting for file lock on package cache
    Rust生命周期之个人理解
    Rust为基础类型实现Trait
  • 原文地址:https://www.cnblogs.com/lixiong-iOS/p/3613924.html
Copyright © 2020-2023  润新知