Изменить высоту UITableViewCell из унаследованного класса UITableViewCell, когда UITextField получает фокус

У меня есть унаследованный класс UITableViewCell, из которого я создаю пользовательскую ячейку, содержащую UITextField.

UITextField по умолчанию имеет высоту 25 пикселей.

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

Я могу определить, когда UITextField получает фокус благодаря уведомлениям и наблюдателям, но мне интересно, как программно сделать так, чтобы tableView:HeightForCellAtindexPath: вызывался.


person VdesmedT    schedule 03.12.2010    source источник


Ответы (3)


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

@class CustomTableViewCell;

@protocol CustomTableViewCellDelegate 
- (void)customTableViewCellDidEnterTextMode:(CustomTableViewCell *)cell;
@end

@protocol (nonatomic, assign) id<CustomTableViewCellDelegate> delegate;

и просто вызовите метод делегата, в котором вы определяете, когда текстовое поле получает фокус

[self.delegate customTableViewCellDidEnterTextMode:self];

и в контроллере

- (void)customTableViewCellDidEnterTextMode:(CustomTableViewCell *)cell {
  self.editingIndexPath = [self.tableView indexPathForCell:cell];
  // from Jablair's answer
  [tableView beginUpdates];
  [tableView endUpdates];
}

А затем в tableView:heightForCellAtIndexPath: просто верните свой особый рост для self.editingIndexPath.

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

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

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

person Robert Höglund    schedule 03.12.2010
comment
Как это будет работать, если один и тот же экземпляр ячейки используется для нескольких строк? - person VdesmedT; 04.12.2010
comment
Нет, один и тот же экземпляр используется только для одной строки за раз. Они используются повторно, но если на экране видно 10 строк, будет 10 разных экземпляров ячейки. - person Robert Höglund; 04.12.2010
comment
Большое Вам спасибо. Я еще не пробовал, но знаю, что это сработает, и ваше последнее объяснение действительно помогло мне понять, почему! Спасибо ! - person VdesmedT; 04.12.2010

Как говорит Endemic, tableView:heightForCellAtIndexPath: — это метод, который вам нужно реализовать. Согласно Apple, наиболее эффективный способ активировать изменение размера — это пустой блок beginUpdates/endUpdates, как этот.

[tableView beginUpdates];
[tableView endUpdates];

Это избавляет вас от накладных расходов на перезагрузку содержимого ячейки и, как мне кажется, дает вам красивую анимацию, которую вы иначе не получили бы от reloadData.

person Jablair    schedule 03.12.2010
comment
Но как мне связать событие, происходящее в унаследованном классе UITableViewCell, и этот фрагмент кода? Это какое-либо свойство или метод, который я могу установить/вызвать в ячейке, который вызовет событие, которое будет запущено в tableViewController? - person VdesmedT; 03.12.2010

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

person Endemic    schedule 03.12.2010
comment
У меня нет никакой ссылки на UITableView внутри ячейки, поэтому это решение заставит меня подключить делегата между tableView и его ячейкой... yak! Однако, спасибо. - person VdesmedT; 03.12.2010