ios - UITableViewCell 上的自定义 subview 和滚动问题

标签 ios performance uitableview scroll cell

我想获得一些关于下面所示代码的建议。滚动在 iPhone 上有点慢,但在模拟器上则不然。我想做的是在每行上显示多个小时和消息,并且每行可能有不同的小时数和消息。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // message + hours
    static NSString *CellIdentifier = @"Cell1";

    // others
    static NSString *CellIdentifier1 = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
    UILabel *hoursLabel;
    UILabel *infoLabel;
    UILabel *dayLabel;

    switch (indexPath.section) {
        case 0:
            cell1 = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];

            if ([hoursArray count] > 0 && [infoArray count] > 0) {
                harray = [self seperateString:[hoursArray objectAtIndex:indexPath.row]];
                iarray = [self seperateString:[infoArray objectAtIndex:indexPath.row]];

                // check how many hours in an array
                int loop = [harray count];
                int currentInfoHeight = 0;
                int currentHourHeight = 0;
                int labelHeight = 0;

                for (int i = 0; i < loop ; i++) {
                    NSString *Text = [[NSString alloc] initWithFormat:@"%@", [harray objectAtIndex:i]];
                    NSString *Text1 = [[NSString alloc] initWithFormat:@"%@", [iarray objectAtIndex:i]];
                    UIFont *cellFont = [UIFont systemFontOfSize:hourfontSize];
                    UIFont *cellFont1 = [UIFont systemFontOfSize:messageFontSize];
                    CGSize constraintSize = CGSizeMake(180.0f, MAXFLOAT);
                    CGSize labelSize = [Text sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
                    CGSize labelSize1 = [Text1 sizeWithFont:cellFont1 constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];


                    /* HourLabel */
                    hoursLabel =
                    [[[UILabel alloc]
                      initWithFrame:
                      CGRectMake(
                                 70.0 + 2.0 * cell1.indentationWidth,
                                 currentHourHeight + gap,
                                 tableView.bounds.size.width - 70.0 - 4.0 * cell1.indentationWidth,
                                 labelSize.height)]
                     autorelease];

                    hoursLabel.text = [NSString stringWithFormat:[harray objectAtIndex:i]];
                    hoursLabel.backgroundColor = [UIColor clearColor];
                    hoursLabel.textColor = [UIColor blackColor];
                    // hoursLabel.shadowColor = [UIColor blackColor];
                    // hoursLabel.shadowOffset = CGSizeMake(0, 1);
                    hoursLabel.font = [UIFont systemFontOfSize:hourfontSize];
                    [cell1.contentView addSubview:hoursLabel];

                    if (![[iarray objectAtIndex:i] isEqualToString:@"-"]) {
                        /* infoLabel */
                        infoLabel =
                        [[[UILabel alloc]
                          initWithFrame:
                          CGRectMake(
                                     70.0 + 2.0 * cell1.indentationWidth,
                                     currentInfoHeight + gap + labelSize.height,
                                     tableView.bounds.size.width - 70.0 - 4.0 * cell1.indentationWidth,
                                     labelSize1.height)]
                         autorelease];


                        infoLabel.text = [NSString stringWithFormat:[iarray objectAtIndex:i]];
                        infoLabel.numberOfLines = 0;
                        infoLabel.backgroundColor = [UIColor clearColor];
                        infoLabel.textColor = [UIColor colorWithRed:51.0/255 green:51.0/255.0 blue:51.0/255.0 alpha:1.0];
                        infoLabel.font = [UIFont systemFontOfSize:messageFontSize];
                        [cell1.contentView addSubview:infoLabel];
                        labelHeight = (infoLabel.bounds.size.height);
                    }
                    else
                    {
                        labelHeight=0;
                    }
                    /* store current height of label */
                    currentHourHeight = (hoursLabel.bounds.size.height) + labelHeight + gap + currentHourHeight;
                    currentInfoHeight = (hoursLabel.bounds.size.height) + labelHeight + gap + currentInfoHeight;

                }
            }

            /* dayLabel */
            dayLabel =
            [[[UILabel alloc]
              initWithFrame:
              CGRectMake(
                         2.0 * cell1.indentationWidth,
                         [self tableView:tableView_ heightForRowAtIndexPath:indexPath] / 2.0f - dayFontSize/2 ,
                         tableView.bounds.size.width -
                         70.0 - 4.0 * cell1.indentationWidth,
                         dayFontSize)]
             autorelease];
            [cell1.contentView addSubview:dayLabel];

            /* Configure the properties for the text that are the same on every row */
            dayLabel.backgroundColor = [UIColor clearColor];
            dayLabel.textColor = [UIColor colorWithRed:207.0/255 green:181.0/255.0 blue:59.0/255.0 alpha:1.0];
            dayLabel.font = [UIFont boldSystemFontOfSize:dayFontSize];
            /* Draw a line to divide info and message into two sections */
            UIView *lineView = [[[UIView alloc] initWithFrame:CGRectMake(79, 0, 1.5, cell1.contentView.bounds.size.height)] autorelease];
            lineView.backgroundColor = [self.tableView_ separatorColor];
            lineView.autoresizingMask = 0x3f;
            [cell1.contentView addSubview:lineView];

            NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
            [formatter setDateFormat:@"EEE"];

            dayLabel.text = [NSString stringWithFormat:[daysArray objectAtIndex:[indexPath row]]];

            [cell1 setSelectionStyle:UITableViewCellSelectionStyleNone];
            return cell1;
        case 1:
            if (cell == nil)
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
            }
            cell.textLabel.text = @"View information for this location";
            cell.textLabel.font = [UIFont systemFontOfSize:16];
            cell.textLabel.textAlignment = UITextAlignmentCenter;
            return cell;
        case 2:
            if (cell == nil)
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

            }
            cell.textLabel.text = @"Show building on campus map";
            cell.textLabel.font = [UIFont systemFontOfSize:16];
            cell.textLabel.textAlignment = UITextAlignmentCenter;
            return cell;
        case 3:
            if (cell == nil)
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

            }
            cell.textLabel.text = @"Direction to building";
            cell.textLabel.font = [UIFont systemFontOfSize:16];
            cell.textLabel.textAlignment = UITextAlignmentCenter;

            return cell;
        default:
            break;
    }
    return cell;
}

最佳答案

  1. 您正在为每个单元格分配一个 NSDateFormatter。根据我的经验,NSDateFormatter 分配和配置是一些最昂贵的调用。它们需要大量时间。
    使 NSDateFormatter 成为一个实例变量,这样您就必须准确地分配和配置它一次。

  2. 您没有重复使用您的细胞。如果您不重复使用单元格,您的性能将会受到影响。 重用的模式是这样的:

.

- (NSDateFormatter *)weekDayDateFormatter {
    if (!myWeekDayDateFormatter) {
        myWeekDayDateFormatter = [[NSDateFormatter alloc] init];
        [myWeekDayDateFormatter setDateFormat:@"EEE"];
    }
    return myWeekDayDateFormatter;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
    static NSInteger secondLabelTag = 1001;
    static NSInteger imageViewTag = 1002;

    static NSString *CellIdentifier1 = @"Cell1";
    static NSString *CellIdentifier2 = @"Cell2";
    UITableViewCell *cell = nil;
    switch (indexPath.section) {
        case 0: {
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
            if (cell == nil) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
                // allocate subviews and configure properties that never change
                UILabel *secondLabel = [[UILabel alloc] initWithFrame:CGRectZero];
                secondLabel.tag = secondLabelTag;
                secondLabel.textColor = [UIColor orangeColor];
                [cell.contentView addSubview:secondLabel];

                UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
                imageView.tag = imageViewTag;
                imageView.contentMode = UIViewContentModeScaleAspectFill;
                [cell.contentView addSubview:imageView];
            }
            // Whatever happened before you have a valid cell here
            UILabel *secondLabel = (UILabel *)[cell.contentView viewWithTag:secondLabelTag];
            UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:imageViewTag];
            secondLabel.text = [self.weekDayDateFormatter stringFromDate:[dataSource objectAtIndex:indexPath.row]];
            imageView.image = [dataSource objectAtIndex:indexPath.row];
            break;
        }
        case 1: {
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
            if (cell == nil) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
                // configure properties that never change between cells
                cell.textLabel.textColor = [UIColor greenColor];
                cell.selectionStyle = UITableViewCellSelectionStyleGray;
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
            }
            // configure properties that are different between cells
            cell.textLabel.text = [dataSource objectAtIndex:indexPath.row];
            cell.textLabel.backgroundColor = [dataSource objectAtIndex:indexPath.row];
            break;
        }

    }

每次调用的tableView:cellForRowAtIndexPath:部分中的代码应该尽可能快地执行。在滚动期间,每个单元格都会调用此方法。

关于ios - UITableViewCell 上的自定义 subview 和滚动问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9816535/

相关文章:

ios - 应该在 UITableViewCell 中调用 deinit 吗?

ios - 在不引用文本字段的情况下关闭键盘

ios - 刷新 UITableView 而不刷新节标题

ios - 有什么方法可以让 "Validate Project Settings"警告在 Xcode 4.3/4.3.1 中消失?

c++ - fwrite 比 Windows 中的 WriteFile 快吗?

.net - ORM 还是直接 SQL?

mysql - 你能用一个查询创建多级数组吗?

ios - 如何在 AFNetworking 2.0+ 中使用 AFHTTPRequestOperationManager 使用 cookie?

ios - UICollectionView 滚动困境

ios - 呈现的 UIViewController 没有在解雇时被释放