Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollView with .viewAligned and .scrollPosition() not updating on orientation / size changes

The scroll position is not updated when orientation changes in a ScrollView with .scrollTargetBehavior(.viewAligned) and .scrollPosition().

SwiftUIScrollViewPOsitionBugSizeChanges

import SwiftUI

struct ContentView: View {
    let colors: [Color] = [.red, .yellow, .cyan, .blue, .teal, .brown, .orange, .indigo]
    @State private var selected: Int? = 0
    
    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 0) {
                ForEach(0..<colors.count, id: \.self) { index in
                    Rectangle()
                        .fill(colors[index])
                        .containerRelativeFrame(.horizontal)
                        .overlay {
                            Text(colors[index].description)
                        }
                }
            }
            .scrollTargetLayout()
        }
        .scrollPosition(id: $selected)
        .scrollTargetBehavior(.viewAligned)
    }
}

#Preview {
    ContentView()
}

@main
struct ViewAlignedScrollBugApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Tested on Xcode 15.3 (15E204a), iOS 17.3.1 iPhone, iOS 17.4 Simulator.

Feedback FB13685677 was submitted to Apple, but in the meantime maybe I am missing something?!

Also on Developer Forums: https://developer.apple.com/forums/thread/748349

like image 272
Calin Avatar asked Dec 22 '25 02:12

Calin


1 Answers

Did you try using the TabView? TabView set to .page is a similar solution that works with orientation changes.

Like this:

enter image description here

Here is example code:

struct ContentView: View {
    let colors: [Color] = [.red, .yellow, .cyan, .blue, .teal, .brown, .orange, .indigo]
    
    var body: some View {
        TabView {
            ForEach(colors, id: \.self) { color in
                Rectangle()
                    .fill(color)
                    .overlay {
                        Text(color.description)
                    }
            }
        }
        .tabViewStyle(.page)
    }
}

Also, if page indicators are not needed then use:

.tabViewStyle(.page(indexDisplayMode: .never))
like image 135
Marcy Avatar answered Dec 24 '25 16:12

Marcy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!