当我使用当前滚动位置滚动到顶部时,如何重新加载 UITableView?(如聊天应用程序)

Woo*_*Kim 3 chat objective-c uitableview ios swift

我现在正在聊天屏幕上工作(UITableView + 输入 TextField)。

我希望UITableView在滚动到顶部时重新加载更多聊天消息保持当前滚动位置(如果我再加载 20 条较旧的消息,我仍然会看到第 21 条消息。)KakaoTalkLine Apps 正在这样做。在那个应用程序中,我可以无限向上滚动,因为滚动位置保持不变。(我的意思是我仍然看到相同的聊天消息)

我正在检查 中的行索引tableView:willDisplayCell:forRowAtIndexPath:,因此当索引为 0 时我获取更多聊天消息。我完成了从 DB 获取更多消息的逻辑,但我没有完成完善 UI。

这是代码。

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.row == 0 && !isTableViewLoading {
        if photo.chatMessages.count != chatMessages.count {
            var loadingChatItems: Array<ChatMessage>

            let start = photo.chatMessages.count - chatMessages.count - Metric.ChatMessageFetchAmount
            if start > 0 {
                loadingChatItems = Database.loadChatMessages(photoId, startIndex: start, amount: Metric.ChatMessageFetchAmount)
            } else {
                loadingChatItems = Database.loadChatMessages(photoId, startIndex: 0, amount: Metric.ChatMessageFetchAmount + start)
            }

            chatMessages = loadingChatItems + chatMessages

            isTableViewLoading = true

            var indexPaths = Array<NSIndexPath>()
            for row in 0..<loadingChatItems.count {
                let indexPath = NSIndexPath(forRow: row, inSection: 0)
                indexPaths.append(indexPath)
            }

            tableView.scrollEnabled = false
            tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.None)
        }
    } else {
        isTableViewLoading = false
        tableView.scrollEnabled = true
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么建议?

And*_*ndo 5

斯威夫特 3

这篇文章有点旧,但这里有一个解决方案:

1) 检测何时滚动到 scrollViewDidScroll 的顶部附近,

2) 加载新消息

3)保存contentSize,重新加载tableView

4) 将tableView的contentOffset.y设置为(newContentSizeHeight - oldContentSizeHeight),也就是当前点

和这里的代码:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView == tableView { 
        if tableView.contentOffset.y < 50 {
            loadMessages()
            let oldContentSizeHeight = tableView.contentSize.height
            tableView.reloadData()
            let newContentSizeHeight = tableView.contentSize.height
            tableView.contentOffset = CGPoint(x:tableView.contentOffset.x,y:newContentSizeHeight - oldContentSizeHeight)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)