Как оживить высоту UITableViewCell с помощью автоматической компоновки?
Есть много похожих вопросов о переполнении стека о анимации высоты UITableViewCell
, но ничего не работает для нового табличного представления iOS8 с автоматической компоновкой. Моя проблема:
Пользовательская ячейка:
@property (weak, nonatomic) IBOutlet iCarousel *carouselView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
@property (weak, nonatomic) IBOutlet UIButton *seeAllButton;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *carouselHeightConstraint;
Примечание carouselHeightConstraint
. Это ограничение по высоте для subview представления контента (единственное подвью).
Высота установлена на 230.0f
, например. При первой загрузке это выглядит так:
![enter image description here]()
Затем в действии Просмотреть все я хочу развернуть ячейку, мой код:
- (IBAction)seeAllButtonAction:(id)sender {
BOOL vertical = !self.carouselCell.carouselView.vertical;
self.carouselCell.carouselView.type = vertical ? iCarouselTypeCylinder : iCarouselTypeLinear;
self.carouselCell.carouselView.vertical = vertical;
[UIView transitionWithView:self.carouselCell.carouselView
duration:0.2
options:0
animations:^{
self.carouselCell.carouselHeightConstraint.constant = vertical ? CGRectGetHeight(self.tableView.frame) : 230;
[self.carouselCell setNeedsUpdateConstraints];
[self.carouselCell updateConstraintsIfNeeded];
[self.tableView beginUpdates];
[self.tableView endUpdates];
completion:^(BOOL finished) {
}];
}
Как вы можете видеть, я стараюсь использовать это хорошее старое решение:
Можете ли вы изменить изменение высоты на UITableViewCell при выборе?
И результат:
![enter image description here]()
Моя ячейка сжимается до 44.0f
height.
Вопрос:
Почему это происходит? Я ожидаю, что моя камера будет плавно расширяться с помощью магии авто-layot.
Примечание:
Я не хочу использовать -tableView:heightForRowAtIndexPath:
. Это авто-макет эры, правильно?
Ответы
Ответ 1
Следующие работали для меня:
Приготовление:
-
В viewDidLoad
скажите в представлении таблицы использование ящиков для самостоятельной калибровки:
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 44; // Some average height of your cells
-
Добавьте ограничения, как обычно, но добавьте их в ячейку contentView
!
Изменение высоты анимации:
Скажем, вы изменили ограничение constant
:
myConstraint.constant = newValue;
... или вы добавляете/удаляете ограничения.
Чтобы оживить это изменение, действуйте следующим образом:
-
Сообщайте contentView о необходимости изменения:
[UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded] }]; // Or self.contentView if you're doing this from your own cell subclass
-
Затем скажите в представлении таблицы реагировать на изменение высоты с помощью анимации
[tableView beginUpdates];
[tableView endUpdates];
Длительность 0,3 на первом этапе - это то, что, по-видимому, является длительностью, которую UITableView использует для своих анимаций при вызове begin/endUpdates.
Бонус - изменение высоты без анимации и без перезагрузки всей таблицы:
Если вы хотите сделать то же самое, что и выше, но без анимации, сделайте следующее:
[cell.contentView layoutIfNeeded];
[UIView setAnimationsEnabled: FALSE];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled: TRUE];
Резюме:
// Height changing code here:
// ...
if (animate) {
[UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded]; }];
[tableView beginUpdates];
[tableView endUpdates];
}
else {
[cell.contentView layoutIfNeeded];
[UIView setAnimationsEnabled: FALSE];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled: TRUE];
}
Вы можете проверить мою реализацию ячейки, которая расширяется, когда пользователь ее выбирает здесь (чистый Swift и чистый автозапуск - поистине путь будущего).
Ответ 2
Я бы хотел добавить несколько слов к ответу на Alex.
Если вы вызываете beginUpdates и endUpdates внутри cellForRowAtIndexPath или willDisplayCell, ваше приложение выйдет из строя. После оживления увеличения вашей ячейки вы можете захотеть, чтобы он остался прежним после прокрутки к таблице TableView. Вы также можете захотеть, чтобы остальные ячейки сохраняли свою высоту одинаково. Но помните, что ячейки многоразовые, поэтому вы можете оказаться в других клетках с повышенной высотой.
В результате вам нужно будет установить константу ограничения внутри cellForRowAtIndexPath в зависимости от элемента, который он представляет. Но если вы вызовете layoutIfNeeded после этого, он отобразит предупреждение с вашими ограничениями. Я убежден, что он пытается сгенерировать компоновку ячеек до того, как будет вычисляться его новая высота.
public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
myConstraint.constant = itemForCell.value == "x" ? 50 : 20 // stop right here
cell.layoutIfNeeded() <- don't do this or some of your constraints will break
beginUpdates() <-- if you do this your app will crash
endUpdates() <-- same here