UITableView 重新加载

Posted

技术标签:

【中文标题】UITableView 重新加载【英文标题】:UITableView reload 【发布时间】:2011-12-16 05:28:12 【问题描述】:

我在重新加载表格时遇到了一些问题。我的cellForRowAtIndexPath 是:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    int counter=indexPath.row;

    NSString *CellIdentifier = [NSString stringWithFormat:@"%d",counter];

    // Dequeue or create a cell of the appropriate type.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) 
    
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        cell.selectionStyle=UITableViewCellSelectionStyleNone;


    //ID
    UILabel *lblID=[[UILabel alloc]init];
    lblID.frame=CGRectMake(10, 15.0, 150, 30.0);
    [lblID setFont:[UIFont boldSystemFontOfSize:20.0]];
    [lblID setBackgroundColor:[UIColor clearColor]];
    [lblID setTextColor:[UIColor blackColor]];
    lblID.text = [arrID objectAtIndex:indexPath.row];
    [cell.contentView addSubview:lblID];
    [lblID release];

    //Date
    UILabel *lblName=[[UILabel alloc]init];
    lblName.frame=CGRectMake(130, 15.0, 250, 30.0);
    [lblName setFont:[UIFont systemFontOfSize:20.0]];
    [lblName setBackgroundColor:[UIColor clearColor]];
    [lblName setTextColor:[UIColor blackColor]];
    lblName.text = [arrProductName objectAtIndex:indexPath.row];
    [cell.contentView addSubview:lblName];
    [lblName release];

    //Qty
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(320, 20, 50, 30)];
    [textField addTarget:self action:@selector(TextOfTextField:)
        forControlEvents:UIControlEventEditingDidEnd];
    textField.userInteractionEnabled = true;
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.font = [UIFont systemFontOfSize:15];
    textField.text = [arrItems objectAtIndex:indexPath.row];
    textField.tag = indexPath.row;
    textField.autocorrectionType = UITextAutocorrectionTypeNo;
    textField.keyboardType = UIKeyboardTypePhonePad;
    textField.returnKeyType = UIReturnKeyDone;
    textField.clearButtonMode = UITextFieldViewModeWhileEditing;
    textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;    
    textField.delegate = self;
    [arrTxtItems addObject:textField];
    [cell.contentView addSubview:textField];
    [textField release];

    //Discount
    UITextField *txtDiscount = [[UITextField alloc] initWithFrame:CGRectMake(460, 20, 50, 30)];
  //  [txtDiscount addTarget:self action:@selector(TextOfTextField:)
    //    forControlEvents:UIControlEventEditingDidEnd];
    txtDiscount.userInteractionEnabled = true;
    txtDiscount.borderStyle = UITextBorderStyleRoundedRect;
    txtDiscount.font = [UIFont systemFontOfSize:15];
    txtDiscount.text = [arrDiscount objectAtIndex:indexPath.row];
    txtDiscount.tag = indexPath.row;
    txtDiscount.autocorrectionType = UITextAutocorrectionTypeNo;
    txtDiscount.keyboardType = UIKeyboardTypePhonePad;
    txtDiscount.returnKeyType = UIReturnKeyDone;
    txtDiscount.clearButtonMode = UITextFieldViewModeWhileEditing;
    txtDiscount.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;    
    txtDiscount.delegate = self;
    [arrTxtDiscount addObject:txtDiscount];
    [cell.contentView addSubview:txtDiscount];
    [txtDiscount release];

    //Price
    UILabel *lblPrice=[[UILabel alloc]init];
    lblPrice.frame=CGRectMake(560, 15.0, 250, 30.0);
    [lblPrice setFont:[UIFont boldSystemFontOfSize:20.0]];
    [lblPrice setBackgroundColor:[UIColor clearColor]];
    [lblPrice setTextColor:[UIColor blackColor]];
    [arrLblNetPrice addObject:lblPrice];
    NSString *strPrice = [arrPrice objectAtIndex:indexPath.row];

    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 
    [formatter setGroupingSeparator:@"."];
    [formatter setGroupingSize:2];
    [formatter setUsesGroupingSeparator:YES];
    [formatter setSecondaryGroupingSize:3];
    NSString *str = [formatter stringFromNumber:[NSNumber numberWithDouble:[strPrice doubleValue]]];
    [formatter release];
    NSLog(@"str :   %@",str);
    NSLog(@"strPrice :    %@",strPrice);
    lblPrice.text = str;
    [cell.contentView addSubview:lblPrice];
    [lblPrice release];
    
        return cell;
  

以这种方式构建单元格有助于我在滚动表格时保留 textFields 的值。但是在某些时候,当我重新加载表格控件时,它并没有落入 if 条件,因为该单元格尚未被释放。在这种情况下我应该在哪里释放细胞?

【问题讨论】:

【参考方案1】:

您需要将创建/获取单元格实例与使用数据配置单元格属性分开。更改代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    int counter=indexPath.row;

    NSString *CellIdentifier = [NSString stringWithFormat:@"%d",counter];

    // Dequeue or create a cell of the appropriate type.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) 
    
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        cell.selectionStyle=UITableViewCellSelectionStyleNone;

        //ID
        UILabel *lblID=[[UILabel alloc]init];
        lblID.frame=CGRectMake(10, 15.0, 150, 30.0);
        [lblID setFont:[UIFont boldSystemFontOfSize:20.0]];
        [lblID setBackgroundColor:[UIColor clearColor]];
        [lblID setTextColor:[UIColor blackColor]];
        lblID.tag = MyViewTagIDLabel;      // make an enum to give your subviews unique tags > 0
        [cell.contentView addSubview:lblID];
        [lblID release];

        // add the rest of your subviews

        // any other cell configuration that does not change based on the ind
    

    // configure the cell with data based on the indexPath
    UILabel lblID = [cell.contentView viewWithTag:MyViewTagIDLabel];
    lblID.text = [arrID objectAtIndex:indexPath.row];

    // configure the rest of the subviews

    return cell;

【讨论】:

@nitish,我刚刚注意到您正在根据indexPath.row 设置单元标识符。由于您的所有单元格都是同一种单元格(例如,具有相同子视图的同一类),您应该对所有单元格使用相同的标识符。通过为每个单元格使用唯一标识符,您违背了 ios 内置的单元格缓存优化的目的。有关详细信息,请参阅 Apple 文档。

以上是关于UITableView 重新加载的主要内容,如果未能解决你的问题,请参考以下文章

如何优化 UITableViewCell,因为我的 UITableView 滞后

重新加载 UITableView 而不重新加载标题部分

等到 UITableview 完成重新加载

重新加载 UITableView 数据而不重新加载视图?

Swift - 重新加载 UITableView 标题

UITableView 重新加载