square/Listable

Support pinning list to bottom as new rows are added

kyleve opened this issue · 11 comments

This allows implementing of the SPOS cart experiences (newest line items added at bottom, always visible), as well as other things like messaging apps.

I think there are two (or more?) features to support here and want to make sure I'm working on ones we need first.

  1. Insetting the top content inset when the content height is less than the view height, so items are always at the bottom of the screen (Messaging apps)
  2. Scrolling to the bottom of the list when a new item is added (which I think is what SPOS needs?)

I assume SPOS doesn't want the behavior of (1). Let me know if I'm wrong here!

Correct, yeah, we'll only want #2 right now! Good catch.

(#1 is actually already there for underflow behaviour, actually, which I didnt realize until I typed that last comment)

I whipped up a demo view controller that just uses the existing scrollTo API to scroll to the last item after it's added. It works decently well. I noticed that the offset doesn't seem to be used at all, since we're forwarding to scrollToItem, which doesn't support an offset.

GIF attached: #101

Oh huh, im surprised that works as well as it does! Nice.

(You're right on the offset – I never moved over to using an API that lets us provide offsets.)

I'll look into supporting the offset, though it probably makes this 10x more complicated 😆 might need that overview first

I think we should be able to do that via using setContentOffset(_:animated:) instead, and then using the collectionViewLayout's layoutAttributesForItem(at:) to get the position – hopefully not super complex... I think

(Also, fwiw, thinking about this more, it would be nice to expose pin to bottom as a config option on the list – so its just a bool for callers to set, vs additional behaviour.)

I totally agree, I started with a property when I was thinking about the API and then noticed this and wanted to see if it worked. Having to just set it would be great though.

One thing I was thinking about yesterday, to control if a row should be scrolled to, we could add a ScrollBehaviour to Item, which could be .none, always, so we could control when an inserted row should be scrolled to.

(That also has the benefit of supporting arbitrary scrolling, not just pinning)