Ios 如何使用自动布局设置UITableViewCell高度的动画?
关于Ios 如何使用自动布局设置UITableViewCell高度的动画?,ios,objective-c,uitableview,ios8,autolayout,Ios,Objective C,Uitableview,Ios8,Autolayout,关于UITableViewCellheight动画,在堆栈溢出方面有很多类似的问题,但是对于新的iOS8自动布局驱动的表视图,没有任何问题可以解决。我的问题: 自定义单元格: @property (weak, nonatomic) IBOutlet iCarousel *carouselView; @property (weak, nonatomic) IBOutlet UIPageControl *pageControl; @property (weak, nonatomic) IBOutle
UITableViewCell
height动画,在堆栈溢出方面有很多类似的问题,但是对于新的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;
注意旋转木马重量限制
。这是内容视图的子视图(唯一的子视图)的高度约束
例如,高度设置为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) {
}];
}
如您所见,我尝试使用这个好的旧解决方案:结果是: 我的手机缩小到
44.0f
高度
问题:
为什么会发生这种情况?我希望看到我的手机在自动布局的魔力下顺利扩展
注意:我不想使用
-tableView:heightforrow索引路径:
。现在是自动布局时代,对吗?以下几点对我来说很有用:
准备:
// 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];
}
viewDidLoad
上,告诉表格视图使用自调整大小的单元格:
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = 44; // Some average height of your cells
contentView
// 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];
}
假设您更改约束的常数
:
myConstraint.constant = newValue;
…或添加/删除约束
要设置此更改的动画,请按以下步骤进行:
[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];
// 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];
}
如果要执行与上面相同的操作,但没有动画,请执行以下操作:
[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&纯自动布局-真正的未来之路)。我想对Alex的答案补充几点 如果您在CellForRowatineXpath或willDisplayCell中调用BeginUpdate和EndUpdate,您的应用程序将崩溃。在设置单元格增加的动画后,您可能希望在滚动到tableView后单元格保持不变。您可能还希望其余单元格的高度保持不变。但请记住,细胞是可重复使用的,因此最终可能会导致其他细胞高度增加 因此,必须在CellForRowatineXpath内设置约束常量,具体取决于它所表示的项。但是,如果随后调用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
public func tableView(tableView:UITableView,cellForRowAtIndexPath:nsindepath)->UITableView单元格{
...
myConstraint.constant=itemForCell.value==“x”?50:20//就停在这里
cell.layoutIfNeeded()单元格您仍然需要使用tableView:heightForRowAtIndexPath:
。这不是一个自动布局作业。@Astoria,看起来很像自动布局作业。@orkenstein我完全同意现在应该使用自动布局来完成这项工作。我正在尝试做基本相同的事情:在单元格的contentView上设置约束,并告诉表视图为单元格设置动画高度。但是,到目前为止,我还不能让它工作。你找到这个问题的解决方案了吗?@Alex,我最终使用了tableView:heightForRowAtIndexPath:
。这似乎是现在唯一的解决方案。虽然很遗憾,但确实如此。别忘了正确更新你的约束条件。@orkenstein在我发布了那条评论之后,我确实设法解决了我的问题,我使用了一种纯粹的自动布局方法:不使用tableView:heightforrowatinexpath:
。如果您仍然感兴趣,可以查看我的解决方案(ExpandableTableViewCell和示例项目)。尽管仍有很多工作在进行中(但它是有效的)。在非动画版本中:调用reloadrowsatindexpath:withRowAnimation:
在表视图上使用UITableViewRowAnimationNone
?而不是禁用UIView
和beginUpdate
/endUpdates
@MichałCiuba上的动画,我不记得我确实尝试过,但我记得er思考:“似乎重新加载rowsatindexpaths:withRowAnimation:
不会重新加载单元格高度。我想我必须尝试其他方法”(可能是为了设置高度动画,而不是即时更新)是的,我的意思是:首先调用layoutIfNeeded
来更新单元格的高度,然后重新加载RowsatindExpaths:withRowAnimation:
来更新表视图。虽然这很好,但请注意,这只会动画到动画的最终状态,而不是介于两者之间。我想强调[tableView BeginUpdate];[tableView endUpdates]
非常重要,如果没有约束,您将在控制台中遇到毫无意义的约束错误。