Swift UI best way to "cover" transition between two views

I have a red and a green view.

When I "toggle cover" the red view should transition away off the bottom of the screen to reveal the green view.

When I "toggle cover" again the red view should transition up from the bottom of the screen to cover the green view.

I have this working in the below code, but to make it work I need to use weird scale: 0.9999 value. Is there a better way to do this?

I tried using .identity transition. I also tried using .scale(scale: 1.0), but in both cases the green view disappears early... can anyone tell me what's going on?

Code Block swift
import SwiftUI
struct TestCoverView: View {
    @State private var showCover = true
    var body: some View {
        VStack {
            Button("Toggle Cover") {
                withAnimation {
                    showCover.toggle()
                }
            }
            if (showCover) {
                Color.red
                    .edgesIgnoringSafeArea(.all)
                    .transition(.move(edge: .bottom))
                    .zIndex(1)
            } else {
                Color.green
                    .edgesIgnoringSafeArea(.all)
                    .transition(.scale(scale: 0.9999))
            }
        }
    }
}

Replies

To try to understand what happens, I tried with a scale of 0.5
  • when green appears, it grows from 0.5 to full (1) whilst red does it reverse transition : moves back to bottom over a green view that grows progressively

  • when red appears, it moves from bottom whilst the green does its inverse transition reducing from 1 to 0.5: you can see it reducing in the background before disappearing under red.

if scale is 1, then in fact there is no transition to animate (1 -> 1). Hence green simply disappear (without animation) whilst red appears, moving from bottom over a white screen (because green has disappeared)

If scale is 0.9999, there is animation (0.9999 -> 1), but that's so close to 1 that the effect is different:
  • when green appears, it grows from 0.9999 to full (1): so it seems to immediately be there whilst red does it reverse transition : moves back to bottom, over a green view

  • when red appears, it moves from bottom whilst the green does its inverse transition reducing from 1 to 0.9999: so green appears to stay in place, covered by the red that moves up.

So what is important here is that you have in fact 2 animation running each time in parallel:
  • red direct and green reverse (when red appears)

  • red inverse and green direct when green appears.

And scale: 1 leads to no transition at all.