I filed FB15170881 about this. When using .scrollPosition on a view that is inside a .navigationDestination, scrolling the ScrollView causes the content to jump around rather than animate smoothly. The same view placed outside of the .navigationDestination scrolls smoothly as expected.
To view this in action, use the example below. It's apparent on MacOS and iOS, as a Preview or run on-device.
- Launch it
- It will load to the problematic view by default.
- Scroll the view in the square to see the janky movement.
You can also press the "back" button to go to a version of the same view that isn't nested inside a .navigationDestination. This one works smoothly as expected.
import SwiftUI
struct ContentView: View {
let items = [0, 1, 2, 3, 4]
@State private var position = ScrollPosition(idType: Int.self)
@State private var showPage: Bool = true
let height = 300.0
let width = 300.0
var body: some View {
NavigationStack {
VStack {
Text("This scrolls nicely.")
Text("It's at the navigation root.")
demoView
Spacer()
Button(action: {
showPage = true
}) {
Text("Go to broken version")
}
.buttonStyle(.bordered)
.navigationDestination(isPresented: $showPage) {
VStack {
Text("This stutters when scrolling.")
Text("It's in a navigationDestination.")
demoView
Spacer()
}
}
Spacer()
}
}
}
@ViewBuilder var demoView: some View {
let _ = Self._printChanges()
ScrollView(.vertical) {
LazyVStack(spacing: 0) {
ForEach(items, id: \.self) { _ in
Text("Scroll me")
.frame(width: width, height: height)
.border(.pink)
}
}
.scrollTargetLayout()
}
.frame(width: width, height: height)
.border(.blue)
.scrollPosition($position)
}
}
#Preview {
ContentView()
.modelContainer(for: Item.self, inMemory: true)
}