Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使用自动布局设置UITableViewCell高度的动画?_Ios_Objective C_Uitableview_Ios8_Autolayout - Fatal编程技术网

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;
    
    …或添加/删除约束

    要设置此更改的动画,请按以下步骤进行:

  • 告诉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时用于动画的持续时间

    奖励-无需动画和重新加载整个表格即可更改高度:

    // 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]
    非常重要,如果没有约束,您将在控制台中遇到毫无意义的约束错误。