【问题标题】:Resize UITableView height, and keep scrolled at bottom调整 UITableView 高度,并在底部保持滚动
【发布时间】:2017-11-06 17:48:59
【问题描述】:

我正在尝试使用动画来调整 tableview 的高度,通过动画 tableview 的 frame.size.height 可以正常工作。

问题是,我有一个高度为 200px 并滚动到底部的 tableview,我想将其设置为 100px,我运行一个简单的

[UIView animateWithDuration:0.245f animations:^{
 CGRect frame = tableview.frame;
 frame.size.height = 100.f;
 tableview.frame = frame;
}];

这工作正常,但在我调整它的大小后,它不再滚动到 tableview 的底部。我希望表格视图在动画时始终在底部滚动。我尝试了很多不同的事情,比如打电话

[tablview scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

就在我开始调整大小动画之前/之后,但我还没有设法让它们 100% 同步。有没有办法在表格视图底部显示滚动视图的最后一个元素时调整表格视图的大小。

【问题讨论】:

  • 使用 [UIView animateWithDuration:animations:completion:] 代替?
  • 我希望滚动动画在调整大小动画之后发生,但谢谢:)

标签: ios


【解决方案1】:

我找到了解决问题的方法,可能会有更好的解决方案,但这实际上效果很好:)

在开始制作动画之前,我会查看 contentSize.height 是否大于目标高度,如果是,我会执行以下操作:

if (mMessages.contentSize.height > 150.f)
{
    CGFloat expandedOffsetY = 52.f;
    CGFloat collapsedBottomOffset = (150.f + 18.f);
    CGFloat expandedBottomOffset = (MIN(320.f, mMessages.contentSize.height) + expandedOffsetY);
    tableFrame.origin.y = (collapsedBottomOffset - expandedBottomOffset) + expandedOffsetY;
}
else
{   
    tableFrame.origin.y = 18.f;
    tableFrame.size.height = 150.f;
}

这会将 tableview 放在负 origin.y 中,然后我将 tableview 包装在带有剪辑子视图 = YES 的“父”uiview 中。

然后我有一个“完成”动画块“重置”到目标值。

CGRect tableFrame = mMessages.frame;
tableFrame.origin.y = 18.f;
tableFrame.size.height = 150.f;
mMessages.frame = tableFrame;

if (mMessages.contentSize.height > tableFrame.size.height)
{
    float contentOffsetY = mMessages.contentSize.height - tableFrame.size.height;
    mMessages.contentOffset = CGPointMake(0.0f, contentOffsetY);
}

【讨论】:

    【解决方案2】:

    尝试在为框架设置动画时更新表格视图的 contentOffset。

    [UIView animateWithDuration:0.245f animations:^{
     CGRect frame = tableview.frame;
     frame.size.height = 100.f;
     tableview.frame = frame;
    
     float contentOffsetY = tableview.contentSize - tableview.frame.size.height;
     tableview.contentOffset = CGPointMake(0, contentOffsetY);
    
    }];
    

    【讨论】:

    • 感谢您的建议,恐怕它看起来不像我想要的那样,在做了一点挖掘之后,它看起来像设置 contentOffsetY 同时设置高度动画会产生一些奇怪的行为(抱歉,但有点难以解释)。但结果并不是 tableview 的底部在调整大小时会向上动画。
    【解决方案3】:
    [UIView animateWithDuration:0.245f  animations:^{
             CGRect frame = tableview.frame;
             frame.size.height = 100.f;
             tableview.frame = frame;
     }  completion:^(BOOL finished) {
            // Find your last indexpath
            [tablview scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
     } ];
    

    【讨论】:

    • 我希望滚动动画在调整大小动画之后发生,但谢谢:)
    【解决方案4】:

    在动画块中将 tableview 滚动到底部对我有用,但有一点点扭曲:当我降低 tableView 的高度时,我在没有动画的情况下调用了 scrollToIndexPath,当我展开 tableView 时,我用动画调用了 scrollToIndexPath。

    UIView.animate(withDuration: 0.25) { [weak self] in
        guard let strongSelf = self
            else { return }
        // ...
        // updateConstraints
        // ...
        strongSelf.view.layoutIfNeeded()
    
        if reduceSize {
            tableView.scrollToLastRow(animated: false)
        } else {
            tableView.scrollToLastRow(animated: true)
        }
    }
    

    UITableView 的扩展

    extension UITableView {
    
        func scrollToLastRow(animated: Bool) {
            let lastSection = numberOfSections-1
            let lastRow = numberOfRows(inSection: lastSection)-1
            let lastIndexPath = IndexPath(row: lastRow, section: lastSection)
            scrollToRow(at: lastIndexPath, at: .bottom, animated: animated)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多