ScrollViewProxy.scrollTo animates long-distance scrolling on Android
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 330
- Forks
- 76
- Avg merge
- 3h 6m
- Merged PRs (30d)
- 1
Description
After upgrading skip-ui from 1.52.0 to 1.56.0, ScrollViewProxy.scrollTo(_:anchor:) on Android frequently performs an animated scroll instead of an instant jump, even when it is not wrapped in withAnimation.
This results in a long visible scroll through the entire list when navigating to items far away in large LazyVStack/List views.
Expected behavior
Calling:
proxy.scrollTo(id, anchor: .top)
outside of withAnimation should immediately jump to the target item (Compose scrollToItem behavior).
Repro
TabView(selection: $mode) {
menuView.tag(Mode.menu)
ScrollViewReader { proxy in
ScrollView {
LazyVStack {
ForEach(items) { item in
Text(item.title)
.id(item.id)
}
}
}
.onChange(of: targetId) { _, newId in
if let newId {
Task { @MainActor in
try? await Task.sleep(for: .milliseconds(300))
proxy.scrollTo(newId, anchor: .top) // Not wrapped in withAnimation
}
}
}
}
.tag(Mode.content)
}
.tabViewStyle(.page(indexDisplayMode: .never))
// Navigation
withAnimation {
targetId = someItemId
mode = .content
}
The navigation to the content page is intentionally animated, but the subsequent proxy.scrollTo call is not. Prior to 1.56.0, this resulted in an immediate jump to the target item. Since upgrading, the scroll itself is animated, suggesting that scrollTo is now using animateScrollToItem instead of scrollToItem in this scenario.
Is this an intentional change in behavior?
If so, is there currently a recommended workaround to force an immediate jump when calling proxy.scrollTo outside of withAnimation?
Additional testing
I patched LazyVStack.swift to always use scrollToItem instead of switching based on Animation.isInWithAnimation.
This restores the previous behavior: proxy.scrollTo immediately jumps to the target item, matching skip-ui 1.52.0.
If appropriate, would it make sense for the default behavior to use scrollToItem across lazy scroll containers, with an explicit API for animated scrolling when desired?
Thanks!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in LazyVStack.swift and trace how Animation.isInWithAnimation selects between scrollToItem and animateScrollToItem. Run the supplied ScrollViewReader reproduction with a large LazyVStack, then verify that scrollTo outside withAnimation jumps immediately while animated navigation remains unaffected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100