Iglistkit: Scrolling loses inertia when rendering more items from data source?

Created on 16 Mar 2018  路  4Comments  路  Source: Instagram/IGListKit

New issue checklist

General information

Debug information

# Please include debug logs using the following lldb command:
po [IGListDebugger dump]

I'm still new to IGListKit so forgive me if I have this all wrong.

In two separate apps, one developed by me and another developed by a co-worker, we've seen scrolling inertia abruptly stop when trying to load more items to our UICollectionView (a la infinite scroll).

They're both implemented similarly to this:

// VideoFeedController.swift
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
  let distance = scrollView.contentSize.height - (targetContentOffset.pointee.y + scrollView.bounds.height)
  if !viewModel.isLoading && distance < 200 {
      loadMore()
  }
}

Where loadMore() is ultimately performing a network request, converting the request into ListDiffable view models, appending to the data source and telling the adapter to perform updates.

UICollectionViewController:

private func load(request: Promise<Void>) {
  adapter.performUpdates(animated: true, completion: nil)
  _ = request.done { [weak self] listing in
    guard let strongSelf = self else {
      return
    }

    strongSelf.adapter.performUpdates(animated: false, completion: nil)
    strongSelf.refresher.endRefreshing()
  }
}

View Model:

@discardableResult
func loadMore() -> Promise<Void> {
  isLoading = true
  return service.perform(pagination: pagination).done { [weak self] listing in
    self?.loaded(listing: listing)
  }
}

private func loaded(listing: VideoFeedListing) {
  isLoading = false
  items.append(contentsOf: listing.items)
  pagination = listing.pagination
}

I've played around with moving loadMore() to a background thread with similar outcome, though I believe network requests from URLSessionDataTask do that automatically?

Here's a screen capture of the bug in action. I've added a print statement for emphasis.

2018-03-16 11 45 48

Thanks for your time and all the hard work on this library 馃憦

question

All 4 comments

My best guess to what's going on is that the target offset after scrolling finished is relative to the content size _before_ the page finishes loading. Then the load finishes before the scrolling animation is done, but the resting offset has already been determined. So your new content loads but the scrolling just ends.

One idea to fix this is to make your loading trigger distance _way_ larger (on Instagram its like 2x your screen height, pretty large).

@achan Did you find a solution? I have the same problem.
@rnystrom I often get stuck when scrolling very quickly and adding new objects
model.append(contentsOf: newElements)
listAdapter?.performUpdates(animated: false, completion: nil)

I did not, @szubiszon. It was a side-project that eventually got dropped 馃槩

I've solved this issue by using

let oldItem = model.items
olditem.append(newItems)
model.items = olditem

//then
listAdapter?.performUpdates(animated: false, completion: nil)
Was this page helpful?
0 / 5 - 0 ratings