2013-08-30 4 views
3

Здравствуйте, я обнаружил, что проблема в моем приложении, возможно, не критическая, но странная.Тупик на UITableViewCell layoutSubviews при назначении accessoriesView

У меня в моем представлении Контроллер коммутатора, назовем его переключателем, когда я заполняю ячейки, на indexPath (0,0) я помещаю этот переключатель в качестве дополнительного вида.

название ячейки изменяется в зависимости от состояния переключателя

//Code simplified for simplicity 
if(indexPath.section == 0 && indexPath.row == 0) { 
    cell.textLabel.text = self.filtersActivatedSwitch.on ? NSLocalizedString(@"Filters activated", nil) : NSLocalizedString(@"Filters deactivated", nil); 
    cell.accessoryView = self.filtersActivatedSwitch; 
} 

При нажатии переключателя этот метод называется

-(void)switchActivated { 
    [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:VisibilityFilterTableViewSectionMasterFilter]]; 
} 

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

Это где это становится сложнее ...

ответ BadPirate объясняют, когда layoutSubview называется на tableviewcell

When is layoutSubviews called?

-addSubview вызывает layoutSubviews быть созванного по мнению добавляемого просмотреть его добавление в (целевой вид) и все подпункты цели

Я думаю, что то же самое должно произойти с removeFromSupperview (предположение), поэтому новая ячейка имеет layoutSubview, называемый ... i t проверяет аксессуар, видит, что он не нуль, поэтому он добавляет его под просмотрку, с другой стороны, в старой ячейке (которая не удалялась по какой-либо причине, поэтому я не мог очистить аксессуар) layoutSubviews вызывается из-за removeFromSuperview (опять же предположение) проверяет, что аксессуар не ноль, он добавляет переключатель в качестве подзаголовка ... и повторяется вечно.

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

Или я пользуюсь аксессуарами. Неправильно?

Cheers!

EDIT: Вот код на prepareForReuse

- (void)prepareForReuse { 
    [super prepareForReuse]; 

    for (UIView *view in self.contentView.subviews) { 
     [view removeFromSuperview]; 
    } 

    for (UIView *view in self.imageView.subviews) { 
     [view removeFromSuperview]; 
    } 

    self.textLabel.text = nil; 
    self.detailTextLabel.text = nil; 
    self.imageView.image = nil; 
    self.imageView.tag = 0; 
    self.accessoryView = nil; 
} 

ответ

2

Клетка повторно, поэтому клетка, которая получает прокручивается от экрана может быть повторно использована в другом месте, с любыми подвидами вы добавили еще там. При добавлении дополнительного вида в определенном indexPath вам нужно иметь предложение «else», чтобы сообщить другим ячейкам, что они не имеют этого представления :. Я не знаю, что еще вы делаете в cellForRowAtIndexPath :, но в моем методе тестирования мне вообще не нужно использовать метод prepareForReuse. Я не уверен, что понимаю, почему вы получаете тупик при запуске метода switch, но все работает, если вы настроили анимацию на UITableViewRowAnimationNone в методе reloadRowsAtIndexPaths: withRowAnimation :.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 

    if(indexPath.section == 0 && indexPath.row == 0) { 
     cell.textLabel.text = self.filtersActivatedSwitch.on ? NSLocalizedString(@"Filters activated", nil) : NSLocalizedString(@"Filters deactivated", nil); 
     cell.accessoryView = self.filtersActivatedSwitch; 
    }else{ 
     cell.textLabel.text = self.theData[indexPath.row]; 
     cell.accessoryView = nil; 
    } 

    return cell; 
} 

-(void)switchActivated { 

    [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; 
} 
+0

cell.accessoryView = UITableViewCellAccessoryNone неправильно, то есть перечисление и accessoryView ожидает объект ... Вы можете передать ноль (это то, что я делать до того, как если ..также это происходит с прокруткой в ​​прокрутке, даже если я только печатаю 1 ячейку, а затем обновляет тупик (фактически, я переопределяю prepareForReuse и устанавливаю все аксессуары для nil) –

+0

@Heavy_Bullets, да, извините, я думал, что это касается аксессуара, а не просмотра. Код, который вы отправили в cellForRowAtIndexPath? Если вы также реализуете prepareForReuse, вы должны опубликовать этот метод, а также весь метод cellForRow. И что вы подразумеваете под DeadLock - что вы видите? – rdelmar

+0

thx, check edit, не очень причудливый просто устанавливает tableviewcell как можно более обнаженным (на клеточном породе он будет заселен) –

Смежные вопросы