0

I am working on a chat app and want when the user is in the bottom of the tableview to have the firebase realtime listener enabled so new rows are added and the tableview scrolls automatically, but when the user is not at the bottom of the table view I don't want the snapshot listener because it automatically scrolls the tableview while the user is trying to read the messages above.

My Solution:

var listener: ListenerRegistration!

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
   
    heightDictionary[indexPath] = cell.frame.size.height
    
    // Trigger pagination when scrolled to last cell
    if (indexPath.row == commentArray.count - 1) {
 
        // Listener is removed so no more realtime updates and tableview does not scroll automaticly
        listener.remove()
        paginate()
        listernerNeedEnable = true
        
    }
    
    // User is at bottom of table view need to enable listener
    if (indexPath.row == 0) {
        print("indexPath.row == 0")
        if listernerNeedEnable == true {
            print("Re enable listiner")

            // NEED TO RE ENABLE LISTENER HERE !!!
            
            listernerNeedEnable = false
            
            
        }
    }
    
}
siamsot
  • 1,501
  • 1
  • 14
  • 20
jmapps9
  • 87
  • 1
  • 7
  • I would suggest a different approach. Instead of enabling and disabling the listener, just leave the listener in place, and let new messages continually be added to the datasource. If the user is not at the bottom of the list, e.g. the last message displayed within the current view is less than the total number of messages, then... don't scroll, leave it in place. You can still refresh the tableView during that process, just don't 'move' their scroll position. – Jay Sep 20 '20 at 14:06
  • @Jay, I tried that but unfortunately it did not work. It keeps on scrolling (changing position when new rows are added). Do you have any suggestion on how I can fix it? – jmapps9 Sep 20 '20 at 15:51
  • 1
    You have control over what's displayed in your tableView. There's a [.scrollToRow](https://developer.apple.com/documentation/uikit/uitableview/1614997-scrolltorow) function which scrolls a row into view. There are a LOT of options as well. Lots of info here on SO. See [here](https://stackoverflow.com/questions/40970176/when-user-uses-back-button-to-uitableview-to-scroll-to-last-selected-row) and [here](https://stackoverflow.com/questions/45205592/uitableview-scroll-to-bottom-from-current-position) – Jay Sep 20 '20 at 17:37

1 Answers1

0

Firestore recommends against a high "churn rate" of listeners and constantly toggling them in this use case could potentially create that. A better approach: if the table is bottomed out when the listener fires then scroll to the bottom after inserting the new cells, otherwise just insert the cells. You can add this extension to simplify things:

extension UIScrollView {
    var isAtBottom: Bool {
        return contentOffset.y >= contentSize.height + contentInset.bottom - bounds.height
    }
}

if tableView.isAtBottom {
    /* insert cells and then scroll to bottom to keep
       the user at the bottom of the screen */
} else {
    /* just insert cells */
}

If your table is jumping or scrolling "on its own" after you insert cells then there is something else going on that may or may not be your doing.

Additionally, you should try to make use of table view batch updates using the performBatchUpdates method. This method gives you the opportunity to scroll to bottom after cells have been inserted (deleted and reloaded as well), which is what you're after.

trndjc
  • 11,654
  • 3
  • 38
  • 51
  • 1
    It think this *scroll to the bottom after inserting the new cells* is what the OP was trying to avoid. e.g. whatever in is in the viewable area when the event occurs, should stay in the viewable area when the event occurs. The description in the answer suggests that if the user is reading the last item in a list and 20 more are added, it will scroll down to the bottom of the list and change what's in the view. Perhaps I misunderstand the intention? – Jay Sep 21 '20 at 17:17