如何使用自动布局animationUITableViewCell高度?
有关堆栈溢出关于UITableViewCell
高度animation很多类似的问题,但没有什么适用于新的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
。 这是内容视图的子视图(唯一的子视图)的高度限制。
例如,高度设置为230.0f
。 在第一次加载它看起来像:
然后,在查看所有操作我想展开单元格,我的代码:
- (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) { }]; }
正如你所看到的,我尝试使用这个古老的解决scheme:
你可以在UITableViewCell上select一个高度变化的animation吗?
结果是:
我的细胞缩小到44.0f
高度。
题:
为什么会发生? 我希望看到我的单元格顺利扩展自动layot的魔力。
注意:
我不想用-tableView:heightForRowAtIndexPath:
这是自动布局时代,对吧?
以下为我工作:
制备:
-
在
viewDidLoad
告诉表视图使用自定义单元格:tableView.rowHeight = UITableViewAutomaticDimension; tableView.estimatedRowHeight = 44; // Some average height of your cells
-
像平常一样添加约束,但将它们添加到单元格的
contentView
!
animation高度变化:
假设你改变一个约束的constant
:
myConstraint.constant = newValue;
…或者你添加/删除约束。
要使此更改生效,请按以下步骤操作:
-
告诉contentView来改变animation:
[UIView animateWithDuration: 0.3 animations: ^{ [cell.contentView layoutIfNeeded] }]; // Or self.contentView if you're doing this from your own cell subclass
-
然后通过animation告诉桌面视图对高度变化做出反应
[tableView beginUpdates]; [tableView endUpdates];
第一步的持续时间为0.3,看起来是UITableView在调用begin / endUpdates时用于animation的持续时间。
奖金 – 更改高度,无需animation,无需重新加载整个表格:
如果你想做同样的事情,但没有animation,那么做这个,而不是:
[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]; }
你可以查看我的实现,当用户在这里select时展开的单元格(纯Swift和纯自动布局 – 真正的未来之路)。
我想补充几点Alex的答案。
如果您在cellForRowAtIndexPath或willDisplayCell中调用beginUpdates和endUpdates,您的应用程序将崩溃。 在animation增加单元格之后,您可能希望在滚动到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