插入新单元格时阻止UITableView滚动

时间:2018-01-06 14:46:09

标签: ios swift uitableview cocoa-touch uiscrollview

我已经多次询问过这个问题,尽管已经实施了社区提出的每个解决方案,但我仍然没有成功。我正在实施的是一个基本的公共聊天应用程序。我需要在UITableView中显示我通过API收到的许多消息。为了有一种聊天的感觉,我通过将转换属性更改为CGAffineTransform(scaleX: 1, y: -1)来颠倒我的UITableView和UITableViewCell。相反,要将单元格添加到UITableView,我首先通过messages.insert(message, at: indexPath.row)将传入消息添加到数组,然后调用insertRows(at: [indexPath], with: animation)(其中 indexPath 以这种方式创建{{1 }})。当我在UITableView的底部时,一切都很棒:新细胞从下到上显示,伴随着平滑的动画。当我向上滚动几个像素时,问题就出现了。看一下这些图像,以便更好地理解其中的差异。

enter image description here enter image description here

我想要实现的是阻止UITableView滚动,除非我处于最底层,这样,如果用户滚动到顶部以读取过去的消息,他可以毫无困难地执行此操作UITableView的运动。

我希望有人能指出我正确的方向。感谢

编辑:如果有帮助,我正在使用自动UITableViewCell高度。

编辑:这是我目前的代码:

我正在使用通用包装器IndexPath(row: 0, section: 0),此方法用于添加新项目:

class ListView<Cell: UITableViewCell, Item>

我必须使用func add(_ item: Item) { items.insert(item, at: 0) if contentOffset.y > -contentInset.top { insertRows(at: [IndexPath(row: 0, section: 0)], with: .top) } else { reloadData() } } 检查我是否位于滚动视图的最底部,因为我之前因为布局原因将contentInset设置为-contentInset.top。我再次将 estimatedRowHeight 设置为44,将 rowHeight 设置为UITableViewAutomaticDimension。

1 个答案:

答案 0 :(得分:2)

func add(_ item: Item) {
    // Calculate your `contentOffset` before adding new row
    let additionalHeight = tableView.contentSize.height - tableView.frame.size.height
    let yOffset = tableView.contentOffset.y

    // Update your contentInset to start tableView from bottom of page
    updateTableContentInset()

    items.append(item)       

    // Create indexPath and add new row at the end
    let indexPath = IndexPath(row: objects.count - 1, section: 0)
    tableView.insertRows(at: [indexPath], with: .top)

    // Scroll to new added row if you are viewing latest messages otherwise stay at where you are
    if yOffset >= additionalHeight {
        tableView.scrollToRow(at: indexPath, at: .top, animated: true)
    }
}

以下是更新contentInset的方法。它将为您提供与此CGAffineTransform(scaleX: 1, y: -1)

相同的效果
func updateTableContentInset() {
    var contentInsetTop = tableView.frame.size.height - tableView.contentSize.height
    if contentInsetTop <= 0 {
        contentInsetTop = 0
    }
    tableView.contentInset = UIEdgeInsets(top: contentInsetTop, left: 0, bottom: 0, right: 0)
}