Повторяющееся содержимое повторно используемых UITableViewCells

#objective-c #ios #cocoa-touch #uitableview

#objective-c #iOS #cocoa-touch #uitableview

Вопрос:

У меня очень распространенная проблема, которую я не знаю, как исправить для себя, даже после прочтения кучи похожих сообщений, поскольку сделать мои ячейки одноразовыми — это не вариант (приложение сильно замедляется).

Проблема

Когда у меня есть 6 или более ячеек (максимум 16), содержимое первых 5 ячеек начинает появляться во всех других ячейках при прокрутке к ним.

Хотя я использую повторно используемые ячейки, почему содержимое моих ячеек не обновляется новыми данными, которые хранятся в моих NSMutableArrays?

Код

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

    WorldClockTableViewCell *worldClockCell = (WorldClockTableViewCell*)[tableView dequeueReusableCellWithIdentifier:kCellID];
if(worldClockCell == nil) {

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"WorldClockTableViewCell" owner:self options:nil];
    worldClockCell = [topLevelObjects objectAtIndex:0];

    /*
     Set Scrolling to OFF by default. 
     User can scroll when table is in edit mode.
     */
    [worldClockCell.scrollView setScrollEnabled:NO];

    // Set Digital Clock in timeLabel
    [self setDigitalClockInLabel:worldClockCell inRow:indexPath.row];

    // Set Analog Clock Carousel in ScrollView in every cell.
    [self setAnalogClocksInScrollView:worldClockCell inRow:indexPath.row];

    // Scroll to User's Preferred Clock (if this is the first launch of WorldClockTableViewController)
    if([[shouldAutoScrollArray objectAtIndex:indexPath.row] boolValue] == YES) {

        [self scrollToUsersPreferredClock:worldClockCell atRow:indexPath.row];
        [shouldAutoScrollArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];

    }   

    // Add City Name to cityLabel in every cell
    [worldClockCell buildFormattedCityName:[model.timeZoneCityNames objectAtIndex:indexPath.row]];

    // Make sure new clocks created while in 'edit' mode don't scroll out of the cell
    worldClockCell.scrollView.frame = worldClockCell.scrollViewFrame;


} 

return worldClockCell;
}
  

Комментарии:

1. Разве некоторые из ваших вызовов методов (например, установка цифровых и аналоговых часов) не должны находиться за пределами блока if (worldClockCell == nil)?

Ответ №1:

Вы выполняете всю настройку своей ячейки, только если она создала новую ячейку, а не если она была удалена из очереди. Вытащите все из

 if(worldClockCell == nil)
  

кроме

 NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"WorldClockTableViewCell" owner:self options:nil];
worldClockCell = [topLevelObjects objectAtIndex:0];
  

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

Комментарии:

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

2. сколько просмотров у вас в ваших ячейках? обычно это не слишком большая проблема. Может быть, вы могли бы опубликовать свои реализации метода, чтобы увидеть, делаете ли вы что-то действительно дорогое. Также рассмотрите возможность использования UINib.

3. У меня есть две метки, один разбитый на страницы scrollview с 6 страницами и два небольших просмотра изображений. Весь код извлекается из пользовательского класса в этот tableviewcontroller. Я проверю UINib.

4. Для большинства сценариев ваше решение будет правильным. Однако для моего сценария это не так из-за scrollViews.

Ответ №2:

Вы должны переместить все цифровые и аналоговые часы из области проверки для удаленной из очереди повторно используемой ячейки, и все будет хорошо. Ваше содержимое повторяется, потому что ячейка, однажды прокрученная вне поля зрения, сохраняется для повторного использования.