iOS Development

ios – The right way to maintain ScrollView+LazyVStack scroll place when including new gadgets

I’ve the next view:

struct NCMediaScrollView: View, Equatable {
    static func == (lhs: NCMediaScrollView, rhs: NCMediaScrollView) -> Bool {
        return lhs.metadatas == rhs.metadatas

    @Binding var metadatas: [tableMetadata]
    @Binding var isInSelectMode: Bool
    @Binding var selectedMetadatas: [tableMetadata]
    @Binding var columnCountStages: [Int]
    @Binding var columnCountStagesIndex: Int
    @Binding var title: String
    @State non-public var dataID: String?

    let queuer: Queuer

    let onCellSelected: (ScaledThumbnail, Bool) -> Void
    let onCellContextMenuItemSelected: (ScaledThumbnail, ContextMenuSelection) -> Void
    let onRefresh: () async -> Void

    var physique: some View {
        let _ = Self._printChanges()

        ScrollView {
            LazyVStack(alignment: .main, spacing: 2) {
                ForEach(metadatas.chunked(into: columnCountStages[columnCountStagesIndex]), id: .self) { rowMetadatas in
                    NCMediaRow(metadatas: rowMetadatas, isInSelectMode: $isInSelectMode, queuer: queuer) { tappedThumbnail, isSelected in
                        onCellSelected(tappedThumbnail, isSelected)
                    } onCellContextMenuItemSelected: { thumbnail, choice in
                        onCellContextMenuItemSelected(thumbnail, choice)
            .padding(.prime, 70)
            .padding(.backside, 40)
        .refreshable {
            await onRefresh()

        .scrollPosition(id: $dataID, anchor: .backside)

Someplace within the father or mother view’s View Mannequin I name:

self.metadatas.insert(contentsOf: updateMetadatas.metadatasUpdate, at: 0)

…so as to add new gadgets to this array. This could then replace the @Binding of metadatas within the above view.

The issue is that the content material offset of the entire scroll view modifications so as to add these views, and in flip the scroll view pushes up as a substitute of remaining on the identical place as earlier than.

Since (I assume) the LazyVStack solely lazily masses views if you scroll downwards, any views which can be added on the highest can be rendered the second they’re added. That is solely an assumption of mine, and the issue could also be one thing else.

What I attempted to repair this:

  1. Utilizing iOS17 scrollTargetLayout + scrollPosition.

The documentation reads:

enter image description here

It is a bit imprecise and complicated, however I had assumed that it could attempt to maintain the focused view on the display screen when a change happens within the ScrollView. Sadly it did not appear to do something.

  1. Capturing the scroll view contentOffset and setting it once more when the array modifications, however as I discussed earlier than, the contentOffset grows when new gadgets are added, so this does not repair something.

Utilizing a Record will not be attainable, since it is a very limiting View and causes loads of performance issues for this tradition view.

Is there any means I can do that?


Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button