iOS:在reloadData时将UITableView保持在相同位置

时间:2018-04-01 08:16:00

标签: ios swift uitableview

我遇到了烦人的问题。我正在做一个消息应用程序。在消息页面中,当用户滚动到顶部时,一旦最顶层的单元格变为可见,它将加载更多消息以显示。因为在加载更多消息时,表视图的位置在顶部(内容偏移为0),在完成加载消息后,我调用reloadData并且iOS尝试保持偏移,从而滚动到表格顶部再次查看并触发另一个负载。这就像一个无限循环,直到没有更多的消息加载。 我试图在scrollToRow之后立即致电reloadData,但没有运气。

所以任何可以使表格视图保持在同一位置的东西(即如果在加载之前,消息" a"位于顶部,加载后,消息" a"仍然在调用reloadData后,屏幕顶部将对我有效。

花了好几个小时,所以我真的很感激任何帮助。感谢

4 个答案:

答案 0 :(得分:3)

我不知道这对你有帮助,但你可以在重装时尝试这个 -

if let indexPaths = tableView.indexPathsForVisibleRows {
    tableView.reloadRows(at: indexPaths, with: .none)
} else {
    tableView.reloadData()
}

答案 1 :(得分:1)

每次只需要插入一行时,不要调用 reloadData ;这是不好的做法。

UITableView的方法有:

func insertRows(at indexPaths: [IndexPath], 
           with animation: UITableViewRowAnimation)

...从iOS 11开始,还有:

func performBatchUpdates(_ updates: (() -> Void)?, 
              completion: ((Bool) -> Void)? = nil)

...允许您作为一个组执行多次插入,删除,重新加载和移动操作。

答案 2 :(得分:0)

使用现代的 swift ,您可以在“仅一行”中使用三进制:

(tableView.indexPathsForVisibleRows)?.isEmpty ?? true ? tableView.reloadData() : tableView.reloadRows(at: tableView.indexPathsForVisibleRows!, with: .none)

答案 3 :(得分:-1)

首先更新modelArray,然后调用TableView的reloadData()方法。

看来你必须实施分页。使用此方法进行api调用,它将在最后一个单元格中调用api。

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    //Bottom Refresh
    if scrollView == yourTableView {
        if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height) {
            if !isNewDataLoading {
                isNewDataLoading = true
                apiCall()
            }
        }
    }
}

确保在API成功响应后将isNewDataLoading设置为false。