Повторное использование ячейки ... :( - PullRequest
0 голосов
/ 15 мая 2011

У меня есть таблица с 9 разделами и 56 строками.

Я хочу добавить текстовую метку для каждой ячейки.Я создал NSArray menuList с 56 NSDictionaries и массивом, содержащим количество строк в каждом разделе (sectionsArray).

Вот мой код, но он не работает должным образомвсе:

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //Use existing cell (reusable)
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];

    //If no existing cell, create a new one
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];

        //Define cell accessory type
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        //Create a subView for the cell
        CGRect subViewFrame = cell.contentView.frame;
        subViewFrame.origin.x += kInset;
        subViewFrame.size.width = kInset + kSelectLabelWidth;

        UILabel *selectedLabel = [[UILabel alloc] initWithFrame:subViewFrame];

        //SubView design
        selectedLabel.textColor = [UIColor blackColor];
        selectedLabel.highlightedTextColor = [UIColor whiteColor];
        selectedLabel.backgroundColor = [UIColor clearColor];

        [cell.contentView addSubview:selectedLabel];

        int indRow = 0;
        for (int i =0; i < indexPath.section; i++) {
            indRow += [[sectionsArray objectAtIndex:i] intValue];
        }
        indRow += indexPath.row;

        NSDictionary *cellText = [menuList objectAtIndex:indRow];

        selectedLabel.text = [cellText objectForKey:@"selection"];
        [selectedLabel release];

    }
    return cell;        
}

Что не так в этом коде?

В iOSSimulator я вижу, что текст ячейки иногда меняется, когда я выполняю прокрутку, а метки не в правильном порядке.

1 Ответ

6 голосов
/ 15 мая 2011

Весь код, который заполняет ваши ячейки, находится в:

if (cell == nil) {

, так что вы в конечном итоге создаете небольшое количество ячеек и заполняете их (когда ячейка == ноль), а затем просто возвращаете устаревшие.

Вот что должно быть:

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //Use existing cell (reusable)
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];

    //If no existing cell, create a new one
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];

        //Define cell accessory type
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

        //Create a subView for the cell
        CGRect subViewFrame = cell.contentView.frame;
        subViewFrame.origin.x += kInset;
        subViewFrame.size.width = kInset + kSelectLabelWidth;

        UILabel *selectedLabel = [[UILabel alloc] initWithFrame:subViewFrame];

        //SubView design
        selectedLabel.textColor = [UIColor blackColor];
        selectedLabel.highlightedTextColor = [UIColor whiteColor];
        selectedLabel.backgroundColor = [UIColor clearColor];

        [cell.contentView addSubview:selectedLabel];
    }
    // At this point cell whether it is a reused cell or a new one
    // cell points to the object we need to fill in.

    int indRow = 0;
    for (int i =0; i < indexPath.section; i++) {
        indRow += [[sectionsArray objectAtIndex:i] intValue];
    }
    indRow += indexPath.row;

    NSDictionary *cellText = [menuList objectAtIndex:indRow];

    selectedLabel.text = [cellText objectForKey:@"selection"];
    [selectedLabel release];

    return cell;       
}

Вот что делает код:

Try to get a reusable cell

If no reusable cell is available
{
    create a new cell
}

Fill in the values for the cell

Таким образом, когда ячейка прокручивается на экране, она помещается в очередь повторного использования. Когда на экран вот-вот выйдет клетка, ваш cellForRowAtIndexPath вызывается. Выделение новой ячейки происходит медленнее, чем повторное использование существующей, поэтому сначала вы пытаетесь получить ячейку из очереди повторного использования, но если она недоступна, вы создаете новую. Затем вы вводите свои значения.

...