【问题标题】:UITableView Custom Cell very slowUITableView 自定义 Cell 很慢
【发布时间】:2011-01-24 18:43:13
【问题描述】:

我有一个 UITableView 并且我创建了一个自定义单元格来显示我的表格。我显示了 6 个 UILables,虽然我只有 20 条记录要显示,但滚动时速度很慢。

这就是我的 - tableView: cellForRowAtIndexPath: 的样子:

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

    static NSString *CustomCellIdentifier = @"CustomCellIdentifier";

    HistoryCell *cell = (HistoryCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];

    if (cell == nil) { 
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"HistoryCell" owner:nil options:nil];

        for (id oneObject in nib)
            if ([oneObject isKindOfClass:[UITableViewCell class]])
                cell = (HistoryCell *) oneObject;
    }

    NSArray *object;
    object = [cours objectForKey: [NSString stringWithFormat:@"%d", indexPath.section]];
    History *rowData = [object objectAtIndex:indexPath.row];

    if (rowData.month == 99) {
        cell.hour.frame = CGRectMake(10, 0, 135, 35);
        cell.data.hidden = YES;
        cell.hour.textColor = [UIColor blackColor];
        cell.hour.font = [UIFont fontWithName:@"Verdana" size:17];
    } else {
        cell.data.hidden = NO;
        cell.hour.frame = CGRectMake(10, 16, 135, 19);
        cell.hour.textColor = [UIColor grayColor];
        cell.hour.font = [UIFont fontWithName:@"Verdana" size:12];
    }

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"d (EEEE)"];
    [formatter setLocale:self.selectedLanguageLocale];
    NSString *stringFromDate = [formatter stringFromDate:rowData.data];
    [formatter release];

    cell.data.text = stringFromDate;
    cell.hour.text = rowData.ora;

    float Var1  = [rowData.Var2 floatValue];
    float Var2  = [rowData.Var2 floatValue];

    cell.R1.text = [self floatToStringFormat: [rowData.R1 floatValue]];
    cell.R2.text = [self floatToStringFormat: [rowData.R2 floatValue]];

    if (Var1 <= 0) {
        cell.Var1.textColor = [UIColor greenColor];
    } else {
        cell.Var1.textColor = [UIColor redColor];
    }
    if (Var2 <= 0) {
        cell.Var2.textColor = [UIColor greenColor];
    } else {
        cell.Var2.textColor = [UIColor redColor];
    }
    cell.Var1.text = [self floatToStringFormat:Var1];
    cell.Var2.text = [self floatToStringFormat:Var2];

    cell.selectionStyle = UITableViewCellSelectionStyleGray;
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

滚动运行缓慢的原因是因为我在这里做的所有事情(NSDateFormatter、CGMakeRect、floatToStringFormat...),还是重复使用单元格有什么问题?

floatToStringFormat 是一个将数字格式化为 4 位小数的函数:

- (NSString *)floatToStringFormat:(float)number{
    NSNumberFormatter *myFloat = [[NSNumberFormatter alloc] init]; 
    [myFloat setFormatterBehavior:NSNumberFormatterBehavior10_4]; 
    [myFloat setNumberStyle:NSNumberFormatterDecimalStyle];
    [myFloat setRoundingMode:NSNumberFormatterRoundHalfUp];
    [myFloat setMinimumFractionDigits:4];
    [myFloat setMaximumFractionDigits:4];
    NSString *res = [myFloat stringFromNumber:[NSNumber numberWithFloat:number]];
    [myFloat release];
    return res;
}

【问题讨论】:

    标签: iphone uitableview custom-cell


    【解决方案1】:

    创建和设置格式化程序对象确实是一项昂贵的操作,因此我将从重用格式化程序对象开始,因为它们在每个函数调用中都是相同的。因此,要么在数据源类中将它们设为静态变量或即时变量,然后按以下方式创建:

    //static variable case
    NSDateFormatter *formatter = nil;
    if (!formatter){
       formatter = [[NSDateFormatter alloc] init];
       [formatter setDateFormat:@"d (EEEE)"];
       [formatter setLocale:self.selectedLanguageLocale];
    }
    NSString *stringFromDate = [formatter stringFromDate:rowData.data];
    ...
    

    【讨论】:

      【解决方案2】:

      首先,您使用了两个不同的标识符:CustomCellIdentifierBanciHistoryCellIdentifier

      其次,每次显示新单元格时,您真的需要在NSArray *object; 之后执行所有操作吗?因为如果不这样做,则应将其移至 if (cell == nil) { 块。

      【讨论】:

      • 其实真正的一个是 BanciHistoryCellIdentifier 但我在这里将它重命名为 CustomCellIdentifier 以便您更容易理解,而这个没有重命名。
      【解决方案3】:

      根据我的经验,如果您有三个或更多子视图(也取决于设备和视图),表格视图单元格的绘制会显着减慢。尝试直接在drawRect中绘制内容:而不是使用子视图,这应该会加快速度。

      【讨论】:

        【解决方案4】:

        你在这里做什么:

        if (cell == nil) { 
                NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"HistoryCell" owner:nil options:nil];
        
                for (id oneObject in nib)
                    if ([oneObject isKindOfClass:[UITableViewCell class]])
                        cell = (HistoryCell *) oneObject;
            }
        

        请阅读documentation,了解如何正确执行此操作。其次,如果将日期和数字转换为字符串花费的时间太长,则改为存储字符串值,并在需要修改它们时将它们转换为值。

        【讨论】:

          【解决方案5】:

          您是否在 Interface builder 中设置了 CellIdentifier?它必须与您在代码中使用的完全匹配。在从 nib 加载单元格的位置设置断点,并确保在滚动时重用单元格。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-05
            • 2017-02-03
            • 2012-07-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多