I have this strange animation bug I’ve not been able to figure out. When transitioning on a view that contains a slider, the slider appears to animate independently of the rest of the view.
For reference, here is the code that animates the two views:
@main
struct TransitionAnimationBug: App {
@State var displaySettings = false
var body: some Scene {
WindowGroup {
Group {
if displaySettings {
SliderView(displaySettings: $displaySettings)
.transition(AnyTransition.asymmetric(
insertion: .move(edge: .trailing),
removal: .move(edge: .leading)
))
} else {
MainView(displaySettings: $displaySettings)
.transition(AnyTransition.asymmetric(
insertion: .move(edge: .leading),
removal: .move(edge: .trailing)
))
}
}
.animation(.easeInOut, value: displaySettings) // Shows bug
// .animation(.spring(), value: displaySettings) // Works
}
}
}
And here is the code from the settings screen that displays the slider:
struct SliderView: View {
var displaySettings: Binding<Bool>
@State var sliderValue: Double = 4.0
init(displaySettings: Binding<Bool>) {
self.displaySettings = displaySettings
}
var body: some View {
VStack(spacing: 30) {
Text("Hello, world!")
Slider(value: $sliderValue, in: 0 ... 4, step: 1)
.border(.red)
.padding(20)
Button("Close") { displaySettings.wrappedValue.toggle() }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.black.opacity(0.2))
}
}
And for completeness the main view:
struct MainView: View {
var displaySettings: Binding<Bool>
init(displaySettings: Binding<Bool>) {
self.displaySettings = displaySettings
}
var body: some View {
VStack(spacing: 30) {
Text("Hello, world!")
.padding()
Button("Show transition bug") {
displaySettings.wrappedValue.toggle()
}
Text("The slider will animate incorrectly")
.padding()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.white)
}
}
As you can see this is a minimal app I built to show the bug (which I’ve submitted to Apple via their Feedback assistant), but I was wondering if anyone here as encountered it and found a solution.
Through experimenting I found that using a .spring() animation instead of .slideInOut correctly animates the slider, but any other animation fails.
Any thoughts?
>Solution :
This is effect of changing root view of window. The fix is to move the content of WindowGroup with all related states into separated view (to make root of window persistent), so it looks like
WindowGroup {
ContentView() // << everything else move here !!
}
Tested with Xcode 13.3 / iOS 15.4
