UITableViewCells вышли из строя - PullRequest
0 голосов
/ 25 января 2012

Хорошо, у меня другая проблема с UITableView. По какой-то причине indexPath.row все перемешано. Когда я закомментирую оператор if, который устанавливает ячейку, все работает нормально. NSLogs говорят мне, что они загружаются по порядку, но все ячейки вышли из строя.

Кажется, они повторяются; Я вижу только 8 клеток, и они повторяются снова и снова.

Вот мой код:

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

static NSString *CellIdentifier = @"Cell";
NSLog(@"row: %d",indexPath.row);

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

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.backgroundColor = [UIColor clearColor];
    cell.contentView.backgroundColor = [UIColor clearColor];

    // Add subviews like this:
    // [[cell contentView] addSubview:objectName];
    // And I get the row number like this: indexPath.row when getting objects from the array

}

return cell;
}

Ответы [ 2 ]

1 голос
/ 25 января 2012

Чтобы использовать ваш код:

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

static NSString *CellIdentifier = @"Cell";
NSLog(@"row: %d",indexPath.row);

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

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.backgroundColor = [UIColor clearColor];
        cell.contentView.backgroundColor = [UIColor clearColor];

        // Add subviews like this:
        // [[cell contentView] addSubview:objectName];


    }
     ### Move this here ###
// And I get the row number like this: indexPath.row when getting objects from the array
return cell;
}

«Я вижу только 8 клеток, и они повторяются снова и снова». Правильно.

Что вы упускаете, так это то, как это должно работать. Вот почему, только если ячейка равна нулю, вы выделяете и запускаете новую ячейку. Таким образом, вы выделяете и инициализируете, устанавливаете цвета и добавляете подпредставления в операторе if. Затем после if(cell==nil) вы знаете, что у вас есть действительная ячейка для заполнения некоторыми данными в соответствии с переданной переменной indexPath.

Проблема в том, что теперь вы настраиваете ячейку, когда она равна нулю, и присваиваете все отображаемые данные в соответствии с переданным indexPath. Проблема в том, что ячейка не равна нулю во второй раз, когда она используется, поэтому данные никогда не менялся.

Для дальнейшего рассмотрения вашего комментария по скорости я буду использовать старый резервный пример.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        UILabel *hugeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, cell.frame.size.width, cell.frame.size.height)];
        hugeLabel.tag = 300;
        [cell addSubview:hugeLabel];
    }
    [(UILabel *)[cell viewWithTag:300] setText:[arrayOfStrings objectAtIndex:indexPath.row]];
    return cell;
}

Если вы посмотрите на пример выше, вы увидите, что мы добавляем UILabel к ячейке, устанавливая для нее тег 300. Затем после оператора if у нас будет либо новая ячейка, либо повторно используемая ячейка с текстом. уже в ярлыке. В любом случае мы просто изменим текст существующего ярлыка на тот, который должен быть в строке. Таким образом мы избегаем создания просмотров снова и снова.

Если вы полностью настроены на кэширование UITableViewCells, вы можете сделать это следующим образом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row < _cells.count){
        return [_cells objectAtIndex:indexPath.row]; // _cells is an NSMutableArray setup in viewDidLoad
    }
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@""];
    cell.textLabel.text = [source objectAtIndex:indexPath.row]; // source is an NSArray of NSStrings I set up in viewDidLoad
    [_cells addObject:cell];
    return cell;
}

Примечание Когда вы запускаете это на устройстве, не удивляйтесь, когда в консоли вы видите Received memory warning То, что эффективно и что легко, часто не одинаково.

0 голосов
/ 25 января 2012

То, как вы его настроили сейчас, cell.selectionStyle, cell.backgroundColor, cell.contentView.backgrounColor и т. Д., Устанавливается только тогда, когда if (cell == nil) имеет значение true.Вам нужно переместить этот код за пределы блока операторов if, чтобы он вызывался как тогда, когда dequeueReusableCellWithIdentifier: производит ячейку, так и когда у нее нет ячеек в инвентаре и ничего не получается (т. Е. Ноль).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...