Animation delay causes animation to be out of sync with the view layout in SwiftUI

99 Views Asked by At

Using a delayed animation on an HStack causes the animation to become out of sync with the view layout. This looks like very simple SwiftUI code.

Without the animation .delay(), everything works fine.

If showView is toggled after the animation has finished, then it works fine.

If showView is toggled when the animation is almost finished, then it will start being out of sync until the animation finishes completely.

// ContentView.swift
import SwiftUI

struct ContentView: View {
    @State private var showView = true
    var body: some View {
        VStack(spacing: 50) {
            HStack {
                Image(systemName: "globe")
                if showView {
                    Text("Hello, world!")
                }
            }
            .animation(.default.delay(1), value: showView) // .delay() here causes the issues
            
            Button("Toggle Text") {
                showView.toggle()
            }
        }
    }
}

#Preview {
    ContentView()
}

AnimationDelay

This happens on the current iOS version (simulator iOS 17.2 and device iOS 17.3.1) and latest Xcode (15.2) at the time of the writing.

1

There are 1 best solutions below

0
Taeeun Kim On

I also could reproduce the bug.
And I could solve it using DispatchQueue.main.asyncAfter

struct ContentView: View {
    @State private var showView = true
    
    var body: some View {
        VStack(spacing: 50) {
            HStack {
                Image(systemName: "globe")
                if showView {
                    Text("Hello, world!")
                }
            }
            .animation(.default, value: showView)
            
            Button("Toggle Text") {
                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                    showView.toggle()
                }
            }
        }
    }
}