UITableViewCell高度变化的动画效果,无需滚动

5

我知道如何使用此处所见的方法(Can you animate a height change on a UITableViewCell when selected?)来使UITableViewCell高度变化得到动画效果。

然而,使用该方法时,UITableView会同时滚动,这并不是我想要的。

我的UITableView只有很少的单元格,不到屏幕高度的大小。最后一个单元格有一个UITextField,当它开始编辑时,我手动设置UITableView的内容偏移量,使包含UITextField的单元格滚动到顶部。然后,根据UITextField中的输入,我可能想要增加UITableViewCell的大小以显示其他选项,数量可能多或少。

问题是,在进行此更改的动画时,它会重新定位UITableView,导致我的UITextField不再在顶部。

大致上,这就是我正在做的事情:

self.customAmountCellSize = height;

[self.tableView beginUpdates];
[self.tableView endUpdates];

我也尝试过

self.customAmountCellSize = height;
CGPoint originalOffset = self.tableView.contentOffset;

[self.tableView beginUpdates];
[self.tableView endUpdates];

[self.tableView setContentOffset:originalOffset animated:NO];

我想要行高度动画,但我不希望UITableView因此滚动。
有什么好的想法吗?

我正在滚动UITableView到一个ContentOffset,这个ContentOffset通常无法通过拖动实现,因为UITableView的内容小于单个屏幕的大小。然而,在编辑时需要将底部单元格滚动到顶部。当我在编辑期间更改底部单元格的大小时,UITableView会滚回到可以通过拖动实现的ContentOffset(在这种情况下,回到ContentOffset(0,0))。 - MikeS
2个回答

3

看起来你遇到的问题是,你的表视图已经向下滚动,所以当你更新它的内容时,它会尝试解决这个问题。

有两种方法可以防止滚动:

  1. Set the table view's content inset to be the height of the initial white space:

    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, verticalGap, 0);
    
  2. Add an empty footer view with the same height as the vertical gap:

    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, verticalGap)];
    

在这两种情况下,您需要计算所需的垂直空间。完成后,您需要将contentInsettableFooterView还原为其原始状态。


有没有可能对tableView的contentInset进行动画处理?编辑:显然是可以的,只需将其放入UIView animateWithDuration块中即可。 - MikeS
@MikeS,没有必要为增长的内容设置动画效果,但是当取消文本字段时,您可以为其设置缩小动画。 - Brian Nickel
是的,缩小部分是问题所在;它会将表格抽回原位而不是以动画方式返回,但使用动画后,它运行得很好。谢谢!我决定按照你提出的第一种选择,在编辑前和编辑后设置contentInset是最好的方法。这比我的重复计时器解决方案要好得多! - MikeS
一旦系统允许,我会立即授予您奖金。再次感谢您。 - MikeS
@MikeS,请注意,使用animateWithDuration动画化UIScrollViewUITableView的部分不会触发scrollViewDidScroll,从而防止自定义行为和单元格出列。如果您看到奇怪的副作用,您可能需要滚动到顶部,然后在动画外删除内容偏移量。 - Brian Nickel

1
我认为表格视图滚动是因为您的文本字段成为了第一响应者,而不是由于单元格高度的改变。尝试保持单元格高度相同,只调整偏移量以确保。
如果我正确的话,那么这就是解决方案:UITableView在键盘出现时会自动尝试滚动。要解决此问题,请将内容偏移设置为所需偏移量,并将其放入主队列中的调度中,在下一个运行循环的开始处触发。将以下代码放入对UIKeyboardWillShowNotification的响应中,或放入UITextFieldDelegate shouldBeginEditing方法中:
// Get the current offset prior to the keyboard animation
CGPoint currentOffset = self.tableView.contentOffset;
UIEdgeInsets currentInsets = self.tableView.contentInset;
__weak SomeTableViewControllerClass *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [UIView animationWithDuration:0 animations:{
        // set the content offset back to what it was
        weakSelf.tableView.contentOffset = currentOffset;
        weakSelf.tableView.contentInset = currentInsets;
    } completion:nil];
});

有时候,根据你的UITableView的框架和其他因素,可能需要类似的修复来解决table view的contentInset.bottom。

我尝试过这个,但它没有起作用。另外,为了澄清,我的UITextField已经是第一响应者了。我想我可能会模拟一个非常快速的项目来演示我遇到的问题... - MikeS
你是否也尝试设置contentInset呢?我会更新我的示例代码来展示给你。请记住,根据您的视图层次结构,contentInset的调整需求会有很大的差异。提供一个示例项目会更有帮助。 - jaredsinclair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接