Пользовательские подпредставления для UITableViewCell и проблема прокрутки - PullRequest
0 голосов
/ 22 марта 2012

Я хотел бы получить некоторые предложения по поводу кода, показанного ниже.На 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;
}

Ответы [ 2 ]

1 голос
/ 22 марта 2012
  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: частях, которые вызываются каждый раз, должен выполняться как можно быстрее,Во время прокрутки этот метод вызывается для каждой ячейки.

0 голосов
/ 22 марта 2012

Полагаю, здесь производительность не потеряна, но в -cellForRowAtIndexPath:

Используете ли вы – prepareForReuse / – dequeueReusableCellWithIdentifier:?

...