### What I expect to happen

I have a meditation view that has an animation subview with a binding property `inhaling` that should appear when a button is pressed.

When the animation subview appears, it should start the animation from the beginning. It's the Apple meditation breathing animation basically: it starts as a small ball and gets bigger as inhaling is true, and then smaller as inhaling is false.

![1](https://i.stack.imgur.com/kFKTnm.png)

When the user presses the button again, the animation should disappear.

When the user then again presses the button, a second time, it should start the animation subview with a binding clean. Meaning the subview is a small ball and gets big again. Like the first time.

```swift
struct Meditation: View {
    @State var startBreathingAnimation = false
    @State var inhaling = false
    @State var infoText = "Start a mediation"

    var body: some View {
        VStack(spacing: 20) {
            ZStack {
                if startBreathingAnimation {
                    BreathAnimation(inhaling: $inhaling)
                        .onChange(of: inhaling) { newValue in
                            if newValue {
                                infoText = "Breath in..."
                            } else {
                                infoText = "Breath out..."
                            }                                }
                        .onDisappear {
                            infoText = "Start your meditation" // Never executed?
                        }
                } else {
                    Circle()
                        .frame(height: 100)
                        .foregroundColor(.blue)
                }
            }
            Text(infoText)
            Button("Toggle") {
                startBreathingAnimation.toggle()
            }
        }
        .padding()
    }
}

```

### What actually happens

The animation subview with a binding is not reset, newly initialized, but starts just where it left off after being "dismissed" with the button press.

When I don't add a binding property into the subview, it actually works as expected: it resets every time and gives me a "fresh" subview. But I do actually need to observe changes to the animation subview property `inhaling` in order to update the `infoText` property in the main view.

### Reproducible example code, ready to copy into Xcode

Any help is greatly appreciated!

```swift
// Can be copied to Xcode directly
struct Meditation: View {
    @State var startBreathingAnimation = false
    @State var inhaling = false
    @State var infoText = "Start a mediation"

    var body: some View {
        VStack(spacing: 20) {
            ZStack {
                if startBreathingAnimation {
                    BreathAnimation(inhaling: $inhaling)
                        .onChange(of: inhaling) { newValue in
                            if newValue {
                                infoText = "Breath in..."
                            } else {
                                infoText = "Breath out..."
                            }                                }
                        .onDisappear {
                            infoText = "Start your meditation" // Never executed?
                        }
                } else {
                    Circle()
                        .frame(height: 100)
                        .foregroundColor(.blue)
                }
            }
            Text(infoText)
            Button("Toggle") {
                startBreathingAnimation.toggle()
            }
        }
        .padding()
    }
}

private let gradientStart = Color.accentColor.opacity(0.9)
private let gradientEnd = Color.accentColor.opacity(1.0)

private let gradient = LinearGradient(gradient: Gradient(colors: [gradientStart, gradientEnd]), startPoint: .top, endPoint: .bottom)
private let maskGradient = LinearGradient(gradient: Gradient(colors: [.black]), startPoint: .top, endPoint: .bottom)

private let maxSize: CGFloat = 150
private let minSize: CGFloat = 30
private let inhaleTime: Double = 8
private let exhaleTime: Double = 8
private let pauseTime: Double = 1.5

private let numberOfPetals = 4
private let bigAngle = 360 / numberOfPetals
private let smallAngle = bigAngle / 2

private let ghostMaxSize: CGFloat = maxSize * 0.99
private let ghostMinSize: CGFloat = maxSize * 0.95

private struct Petals: View {
    let size: CGFloat
    let inhaling: Bool

    var isMask = false

    var body: some View {
        let petalsGradient = isMask ? maskGradient : gradient

        ZStack {
            ForEach(0..<numberOfPetals) { index in
                petalsGradient
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .mask(
                        Circle()
                            .frame(width: size, height: size)
                            .offset(x: inhaling ? size * 0.5 : 0)
                            .rotationEffect(.degrees(Double(bigAngle * index)))
                    )
                    .blendMode(isMask ? .normal : .screen)
            }
        }
    }
}

struct BreathAnimation: View {
    @State private var size = minSize
    @Binding var inhaling: Bool

    @State private var ghostSize = ghostMaxSize
    @State private var ghostBlur: CGFloat = 0
    @State private var ghostOpacity: Double = 0

    var body: some View {
        ZStack {
//            Color.black
//                .edgesIgnoringSafeArea(.all)

            ZStack {
                // ghosting for exhaling
                Petals(size: ghostSize, inhaling: inhaling)
                    .blur(radius: ghostBlur)
                    .opacity(ghostOpacity)

                // the mask is important, otherwise there is a color
                // 'jump' when exhaling
                Petals(size: size, inhaling: inhaling, isMask: true)

                // overlapping petals
                Petals(size: size, inhaling: inhaling)
                Petals(size: size, inhaling: inhaling)
                    .rotationEffect(.degrees(Double(smallAngle)))
                    .opacity(inhaling ? 0.8 : 0.6)
            }
            .rotationEffect(.degrees(Double(inhaling ? bigAngle : -smallAngle)))
            .drawingGroup()
        }
        .onAppear {
            performAnimations()
        }
        .onDisappear {
            size = minSize
            inhaling = false
            ghostSize = ghostMaxSize
            ghostBlur = 0
            ghostOpacity = 0
        }
    }
    func performAnimations() {
        withAnimation(.easeInOut(duration: inhaleTime)) {
            inhaling = true
            size = maxSize
        }
        Timer.scheduledTimer(withTimeInterval: inhaleTime + pauseTime, repeats: false) { _ in
            ghostSize = ghostMaxSize
            ghostBlur = 0
            ghostOpacity = 0.8

            Timer.scheduledTimer(withTimeInterval: exhaleTime * 0.2, repeats: false) { _ in
                withAnimation(.easeOut(duration: exhaleTime * 0.6)) {
                    ghostBlur = 30
                    ghostOpacity = 0
                }
            }

            withAnimation(.easeInOut(duration: exhaleTime)) {
                inhaling = false
                size = minSize
                ghostSize = ghostMinSize
            }
        }

        Timer.scheduledTimer(withTimeInterval: inhaleTime + pauseTime + exhaleTime + pauseTime, repeats: false) { _ in

            // endless animation!
            performAnimations()
        }
    }

    private func performAnimations2() {
        withAnimation(.easeInOut(duration: inhaleTime)) {
            inhaling = true
            size = maxSize
        }
        Timer.scheduledTimer(withTimeInterval: inhaleTime + pauseTime, repeats: false) { _ in
            ghostSize = ghostMaxSize
            ghostBlur = 0
            ghostOpacity = 0.8

            Timer.scheduledTimer(withTimeInterval: exhaleTime * 0.2, repeats: false) { _ in
                withAnimation(.easeOut(duration: exhaleTime * 0.6)) {
                    ghostBlur = 30
                    ghostOpacity = 0
                }
            }

            withAnimation(.easeInOut(duration: exhaleTime)) {
                inhaling = false
                size = minSize
                ghostSize = ghostMinSize
            }
        }

        Timer.scheduledTimer(withTimeInterval: inhaleTime + pauseTime + exhaleTime + pauseTime, repeats: false) { _ in

            // endless animation!
            performAnimations()
        }
    }
}

struct MainView_Previews: PreviewProvider {

    static var previews: some View {
        Meditation()
    }
}

```