ios – Sustaining a secure scroll place when inserting gadgets above in a ScrollView

0
7
ios – Sustaining a secure scroll place when inserting gadgets above in a ScrollView


Because the title says, I’m not certain tips on how to correctly construct an inverted ScrollView the place I can safely insert gadgets above my information (“prepend”) with out all the pieces leaping round.

My present code is actually this:

@State non-public var scrollPosition = ScrollPosition(idType: Message.ID.self)

non-public func onMessageDidScrollIntoView(_ id: Message.ID) {
  let indexOfVisibleMessage = /* ... */
  if indexOfVisibleMessage < 10 {
    fetchOlderMessages()
    // ^ this updates my ViewModel `messages`
  }
}

var physique: some View {
  ScrollView {
    LazyVStack {
      ForEach(messages) { message in
        MessageCell(message)
      }
    }.scrollTargetLayout()
  }
  .defaultScrollAnchor(.backside)
  .scrollPosition($scrollPosition)
  .onChange(of: scrollPosition) { oldValue, newValue in
    guard let visibleMessageId = scrollPosition.viewID(sort: Message.ID.self) else { return }
    onMessageDidScrollIntoView(visibleMessageId)
  }
}

..so if the consumer scrolls as much as the oldest 10 messages, I begin loading extra and insert them on the high.

The issue with that is that the ScrollView now jumps when new messages are inserted. It’s because the ScrollView maintains it is Y place, however the content material dimension adjustments since we’re including new gadgets “above”.

I attempted to mess around with just a few strategies I discovered on StackOverflow, particularly;

  • Inverting the ScrollView (.scaleEffect(y: -1) on the ScrollView after which once more on the MessageCell to counter it): This by some means jumped the x place of the ScrollView and utterly breaks .contextMenu.
  • Taking part in round with .onScrollGeometryChange to replace scrollPosition.scrollTo(y:) when it is contentSize adjustments: This simply did not work and stopped the consumer scroll gesture/interplay.
  • Setting scrollPosition to the Message.ID I need to preserve secure earlier than doing an replace: This did not do something.

However nothing really labored for the explanations described above.

How do you really construct these UIs in SwiftUI? I believe an inverted ScrollView is sort of a standard UI, and clearly information must be loaded lazily.

LEAVE A REPLY

Please enter your comment!
Please enter your name here