MessageKit: Random crash when calling `scrollToBottom` with "Invalid update: invalid number of items in section 0"

According to SO, there is a bug with UICollectionView’s performBatchUpdate that could cause crashes in certain cases, and adding a collectionView.numberOfItems(inSection) fixes it: https://stackoverflow.com/a/46751421/1032900

In our case, one user faced frequent crashes when we call scrollToBottom in viewWillAppear for a child of MessagesViewController, and by adding numberOfItems(inSection: 0) before this line: https://github.com/MessageKit/MessageKit/blob/69c5414c224a98891e14984e83228740e4339219/Sources/Views/MessagesCollectionView.swift#L92 did fix it.

Should we consider adding numberOfItems(inSection: 0)? What you guys think?

  • What version of MessageKit are you using? 1.0-beta.1
  • What version of iOS are you running on? 11.1 - 11.4
  • What version of Swift are you running on? 4.1
  • What device(s) are you testing on? Are these simulators? iPhone 8 Plus & iPhone X, not simulators.
  • Is the issue you’re experiencing reproducable in the example app? Not so far

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 27 (19 by maintainers)

Most upvoted comments

Based on @hyouuu answer, You can also implement something like

to be safe when there no content and you call scrollToBottom

    public func scrollToBottom(animated: Bool = false) {
        guard numberOfSections > 0 else { return }
        let lastSection = numberOfSections - 1
        let indexPath = IndexPath(row: 0, section: lastSection)
        scrollToItem(at: indexPath, at: UICollectionView.ScrollPosition.top, animated: animated)
    }

True all the hard to fix bugs I’ve faces originate from Apple’s bugs, and they never fix them 😕

@SD10 I do understand that part as you already stated it in your previous comment. My question was why not using scrollToItem method from UICollectionView. Did an experiment and by changing the function to the following it works perfectly for me (smoother too):

public func scrollToBottom(animated: Bool = false) {
        let lastSection = numberOfSections - 1
        let lastItem = numberOfItems(inSection: lastSection) - 1
        // Using centeredVertically so that footer is shown too
        scrollToItem(at: IndexPath(item: lastItem, section: lastSection), at: .centeredVertically, animated: animated)
}

Hi, is this issue fixed already? I am on 4.2.0, and scrollToLastItem doesn’t correctly scroll to the bottom for me

@lshannak The issue #939 seems to be an issue not related to MessageKit. This is a common error when reloading rows/sections in a collectionView/tableView API. Please make sure you’re updating your view correctly.

If you’re confident everything is correct – and the problem is MessageKit’s scrollToBottom() method. Then you can subclass MessagesCollectionView and override the scrollToBottom() method to provide your own implementation that does not use the performBatchUpdates API

@lshannak I haven’t taken a deep look into this. I’m sorry this is causing frustration, but I wouldn’t say it makes the library unusable. Its not a function that we require you to call.

Like Steven said it’s not ideal but it’s currently the best we have. Perhaps you can come up with something that works better for you specifically as I think a main pain point is that while this works for some, it doesn’t for others and it’s hard to find that one size fits all solution.

Sent with GitHawk

Great to know it’s a confirmed bug - wonder what do you use for your own app? What’s the initial reason not to use UICollectionView’s open func scrollToItem(at indexPath: IndexPath, at scrollPosition: UICollectionViewScrollPosition, animated: Bool)?