Robert Constantinescu
Robert Constantinescu

Reputation: 349

iOS UITableViewController - Insert and Scroll to bottom - sometimes jumping

I'm developing an iOS Chat App and I have a problem on the chat view. I'm using UITableViewController for the chat view. Sometimes my table jumps when new row is inserted as you can see in video: https://youtu.be/8IgEUJ5uYAc .

This is how I'm inserting and scrolling to the bottom of the table:

        self.conversation.append(message)

        self.tableView.beginUpdates()
        self.tableView.insertRows(at: [IndexPath(row: self.conversation.count - 1, section: 0)], with: UITableViewRowAnimation.none)
        self.tableView.endUpdates()


        DispatchQueue.main.async {
            self.tableView.scrollToRow(at: IndexPath(row: self.conversation.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: false)
            self.footerView?.isHidden = true
            self.theMessage.text = nil
            self.switchBottomActions(showSend: false)
        }

Each message object has a property called estimatedMessageHeight. I'm saving there the message cell size, so tableView's heightForRowAt code is:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    guard let cellHeight = self.conversation[indexPath.row].estimatedHeight else {

        return 0

    }

    return cellHeight

}

Any solution?

Upvotes: 2

Views: 2306

Answers (3)

Ahmad Taalab
Ahmad Taalab

Reputation: 215

Make this function:

func scrollToBottom(){
    DispatchQueue.main.async {
        let indexPath = IndexPath(row: self.chatListDB.count-1, section: 0)
        self.tblView.scrollToRow(at: indexPath, at: .bottom, animated: false)
    }
}

and call it after inserting the value.

Upvotes: 0

Ganesh G
Ganesh G

Reputation: 2061

I was also facing same issue and finally I ended up with following solution. It gives me same animation feel like we have in WhatsApp app.

UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations: {

        let reloadIndexPath = IndexPath(item: self.arrTableVwData.count - 1, section: 0)

        self.tableVw.beginUpdates()
        self.tableVw.insertRows(at:[reloadIndexPath], with: UITableViewRowAnimation.fade) 
        self.tableVw.endUpdates()
        self.tableVw.scrollToRow(at: reloadIndexPath, at: .bottom, animated: false)

    }, completion: nil)

NOTE: please do not pass any animation types in options:[] as we already passing them in insertRows and scrollToRow methods.

Upvotes: 4

Beri
Beri

Reputation: 59

You should uncheck Bounce Vertically in the Attribute Inspector for your UITableView.enter image description here

Upvotes: -1

Related Questions