SwiftUI – ScrollViewProxy scrollTo Animation Disappear in iOS 17 – Ios

by
Ali Hasan
axios swift-concurrency swiftui-animation swiftui-ontapgesture

Quick Fix: The bug with the scrollTo animation disappearing in iOS 17 has been resolved in the latest Developer Beta 7 build (21A5319a). The animation is now working as expected. Please update to this build to regain the scrollTo animation functionality.

The Problem:

In SwiftUI, using proxy.scrollTo() to scroll to a target within a ScrollViewReader works differently in iOS 17 compared to iOS 16. When using the code withAnimation { proxy.scrollTo(15, anchor: .top) } to animate the scrolling process, the animation is present in iOS 16 but absent in iOS 17. Is this an API change or a bug?

The Solutions:

Solution 1: Update to iOS 17.0 build 21A5319a (Developer Beta 7)

The issue you’re facing with the ScrollViewProxy scrollTo animation disappearing in iOS 17 was a bug that has been fixed in the latest iOS 17.0 build 21A5319a (Developer Beta 7). By updating to this build, you should regain the animation functionality for the scrollTo action.

Solution 2: Apple Bug fixed

In iOS 17, the issue described in the problem statement was caused by a bug. This bug has been addressed and resolved in the iOS 17 beta 5 update. Therefore, the provided code should now function properly with the desired animation when scrolling to the target. You can update to the latest beta version to experience the fix.

Solution 3: Use the New `.scrollPosition()` Modifier

The ScrollViewReader is no longer available in iOS 17 and has been replaced with a new .scrollPosition() modifier. This new modifier allows you to specify a target position for the scroll view to scroll to. To animate the scrolling process, you can wrap the withAnimation modifier around the .scrollPosition() modifier.

struct ContentView: View {
    @State private var position: Int?

    var body: some View {
        ScrollView {
            LazyVStack {
                Button("Jump...") {
                    withAnimation {
                        position = 99
                    }
                }

                ForEach(0..<100) { index in
                    Rectangle()
                        .fill(Color.green.gradient)
                        .frame(height: 300)
                        .id(index)
                }
            }
            .scrollTargetLayout()
        }
        .scrollPosition(id: $position)
    }
}

In this example:

  • The @State property position is used to store the target position for the scroll view.
  • The Button is used to trigger the scrolling animation.
  • The withAnimation modifier is used to animate the scrolling process.
  • The .scrollPosition() modifier is used to specify the target position for the scroll view.

When the Button is pressed, the withAnimation modifier is triggered, which animates the scrolling process to the target position specified by the .scrollPosition() modifier.

Q&A

In iOS 17, proxy.scrollTo() does not animate anymore. Is this a bug or an API change?

It is a bug that has been fixed in iOS 17 beta 5.

Is there a new API to replace ScrollViewReader?

Yes, use .scrollPosition() modifier instead.

What is the correct way to use .scrollPosition()?

Provide an id to .scrollTargetLayout() and bind it to scrollPosition.

Video Explanation:

The following video, titled "SwiftUI ScrollViewProxy scrollTo Animation Disappear in iOS 17 ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Welcome to Mixible, your go-to source for comprehensive and informative content covering a broad range of topics from Stack Exchange ...