@Sweeper answer got me thinking whether this can be done in a more platform-agnostic way. And there is.
One can use withTransaction
with a transaction that has disablesAnimations
set to true
.
@MainActor
func withoutAnimations(
perform job: @MainActor @escaping () -> Void,
withDelay delay: RunWithoutAnimationDelay = .defaultAnimationDuration
) {
Task { @MainActor in
try await Task.sleep(for: delay.duration)
try withTransaction(.noAnimationTransaction(), job)
}
}
Delay is necessary for the UI machinery to finish current navigation. Otherwise there will be an error
Update NavigationRequestObserver tried to update multiple times per frame.
Using proposed 1ms delay causes animation glitches. So I've opted for a different delay value.
Full gist here
Usage:
// this changes the top of the navigation path to "Something Else"
path.append("Something Else")
withoutAnimations {
path.removeLast(2)
path.append("Something Else")
}