Как избежать дублирования строк при создании UITableViewCell из подпредставлений UILabel - PullRequest
0 голосов
/ 04 декабря 2011

Я загружаю массив элементов словаря, содержащих данные о состоянии США, в UITableView, и у меня возникают повторяющиеся строки, когда пользователь выполняет прокрутку вниз до элементов вне экрана - строка 1 дублируется в строке 8, строка 2 дублируется в строке 9и т. д.

Я рассмотрел следующие вопросы SO и реализовал некоторые из их предложений (без успеха):

2994472 - Мой UITableView содержит повторяющиеся строки

7056578 - повторяющиеся ячейки UITableView при прокрутке

UITableViewCell - это пользовательская конструкция, созданная из UILabels.Вот код в cellForRowAtIndexPath.

00    const int ABBREVIATION = 1, STATE = 2 // Declared outside cellForRowAtIndexPath


01    static NSString *CellIdentifier = @"Cell";
02    
03    UILabel *abbreviation, *state;
04    
05    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
06    if (cell == nil) {
07        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault         
08              reuseIdentifier:CellIdentifier];
09        
10        abbreviation = [[UILabel alloc] initWithFrame:CGRectMake(7.0, 1.0, 34.0, 30.0 )];
11        abbreviation.tag = ABBREVIATION; 
12        abbreviation.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
13        abbreviation.textAlignment = UITextAlignmentLeft;
14        abbreviation.textColor = [UIColor blackColor];
15
16        state = [[UILabel alloc] initWithFrame:CGRectMake(42.0, 1.0, 158.0, 30.0)];
17        state.tag = STATE;
18        state.font = [UIFont fontWithName:@"Helvetica-Bold" size:20.0];
19        state.textAlignment = UITextAlignmentLeft;
20        state.textColor = [UIColor blackColor];
21
22        [cell.contentView addSubview:abbreviation];
23        [cell.contentView addSubview:state];
24    
25        [cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
26        [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
27    }
28    
29    abbreviation.text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"];
30    state.text = [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"];
31    
32    return cell;

Следуйте совету в 2994472, я изменил строки 27 и 28, чтобы использовать троичный оператор.

29   abbreviation.text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"] ?
                         [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"] :
                         @"";

30   state.text = [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"] ?
                  [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"] : 
                  @"";

Это не сработало, дублированиевсе еще происходит, начиная со строки 8.

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

29  ((UILabel *)[cell viewWithTag:ABBREVIATION]).text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"];
30  ((UILabel *)[cell viewWithTag:STATE]).text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"name"];

Когда подпредставления ячейкиссылаются таким образом, что дублирование строки UITableView исчезает.

Ответы [ 2 ]

1 голос
/ 13 декабря 2011

Несмотря на то, что я смог опубликовать решение в своем первоначальном вопросе, я все еще задавался вопросом, почему сначала возникла ситуация с дублирующимися ячейками.

Провел дополнительное исследование, выписав текстовые значения для состояний и сокращений вместе со значениями, отображаемыми в ячейках.

(A) NSLog(@"%@", state.text);
(B) NSLog(@"%@", ((UILabel *)[cell viewWithTag:STATE]).text);

Отображаемые результаты интересны и проливают свет на ситуацию.

 (A)               (B)
 Iowa              Iowa
 New Hampshire     New Hampshire
 South Carolina    South Carolina
 Florida           Florida
 Nevada            Nevada
 Colorado          Colorado
 Minnesota         Minnesota
 (null)            Iowa
 (null)            New Hampshire
 (null)            SouthCarolina
 (null)            Florida

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

Итак, я думаю, что когда прокручивается вниз, исходный код в строках 29 и 30 пытается установить текстовые значения двух переменных экземпляра.

29    abbreviation.text = [[self.primaries objectAtIndex:indexPath.row] objectForKey:@"abbreviation"];
30    state.text = [[self.stateInfo objectAtIndex:indexPath.row] objectForKey:@"name"];

Но так как ARC автоматически разыменовывает их, они больше не существуют, не могут быть установлены и возвращают значение null. Однако ячейки, содержащие исходные значения, «удаляются» и повторно используются со старыми данными, что приводит к появлению дубликатов.

Дайте мне знать, полностью ли я не согласен с этой гипотезой.

0 голосов
/ 04 декабря 2011

Похоже, что в случае dequeueReusableCellWithIdentifier: возвращает существующую ячейку табличного представления, так что ваш блок if пропущен, а переменные abbreviation и state не установлены.Таким образом, в этом случае (что происходит, когда вы начинаете прокручивать и, таким образом, отображать повторно используемые ячейки), abbreviation и state равны нулю в конце вашей функции, поэтому метки повторно используемой ячейки не обновляются, как вы ожидаете.Возможно, вам нужен блок else, в котором вы устанавливаете аббревиатуру и переменные состояния, чтобы указывать на правильные подпредставления cell.

...