SwiftUI bottom-first List (inverted)

How can I create a List that starts on the bottom? 

All Lists start on top, but in a chat, the desired content scroll direction is up (inverted).

There are workarounds that rely on flipping the list with rotation effects, but these don’t work well, and make the logic very hard to understand.

Scrolling to bottom after some delay on list appear has side effects (loads rows on top).

Ideally there would be List { … }.scrollDirection(.inverted) api, that automatically loads the list from its last item, not first.

  • I submitted my feedback in FB9148104

Add a Comment

Replies

Did you try reversing the array you use with ForEach ?

Like :

ForEach(myArray.reversed(), id: \.self) { }
  • Did you read my question? reversing the items of the list doesn't bear on it's starting position visually.

Add a Comment

I think this is more complicated than just using reversed data.

In chat you want to keep offset from the bottom. So when user opens a chat the last (the most recent one) message should be visible, basically bottom content offset is 0. Then, when the chat loads more history, it should keep the current bottom offset. Unfortunately, SwiftUI implementation inserts items from the top and keeps top offset, as it was already mentioned. Also, there is no direct control of scrollview offset in SwiftUI. You could try to use ScrollViewReader for initial loading but not for future history loads because the API is very limited.

Flipping the list and then all the items inside back seems like the most suitable solution but it opens a lot of issues (navbar jumping, pull to refresh, scroll indicator direction) and adds extra complexity for the code.

Described chat use case seems quite common, I'd vote for an extra special modifier as well.

  • Yes I currently use the ScrollViewReader workaround to scroll to bottom on initial list load. Unfortionately, it has side effects and uses delays to achieve a reliable scroll to bottom. With UITableView this was possible by calling reloadData() before setting the content offset of the list to content height on first load (as described here). In SwiftUI this API is unavailable (unless you use Introspect). - though I had no success with it).

Add a Comment