How to remove background of a view with different Transition?

51 Views Asked by At

I'll provide a simplified example. Let's say when I toggle I want to instantly remove the background of the text without any transition or animation, but have the text itself fade out with opacity. How can I achieve this? Please, do not suggest using a ZStack instead of .background; I am looking for a solution in this specific scenario. If it's not possible, please let me know.

struct BackgroundTransition: View {

    @State var show = true
    
    var body: some View {
        VStack {
    
            Group {
                if show {
                    Text("Some Text")
                        .background(
                            Color.blue
                                .transition(.identity)
                                .animation(.none, value: show)
                        )
    
                } else {
                    Spacer()
                        .frame(maxHeight: .infinity)
                }
            }
            .frame(height: 50)
    
            Button("Toggle") {
                withAnimation {
                    show.toggle()
                }
            }
    
        }
    }

}

I tried applying .identity transition to the background view and .none animation, but it didn't work.

1

There are 1 best solutions below

2
MatBuompy On

The only way I can think of is having two separate variables: one animated, the other not.

struct BackgroundTransition: View {

    @State var show = true
    @State var showBackground = true
    
    var body: some View {
        VStack {
            
            Group {
                
                Text("Some Text")
                    .opacity(show ? 1 : 0)
                    .background {
                        if showBackground {
                            Color.blue
                                .transition(.identity)
                        }
                    }
                
                if !showBackground {
                    Spacer()
                        .frame(maxHeight: .infinity)
                }
                
            }
            .frame(height: 50)
    
            Button("Toggle") {
                withAnimation {
                    show.toggle()
                }
                /// Do not animate this
                showBackground.toggle()
            }
    
        }
    }

}

I removed the if in order to do so, otherwise all the Views inside would have been animated regardless of any other condition. I didn't know how to handle the Spacer this case though, since it is pushing the View as soon as the toggle button is tapped. Try this out anyway and let me know what you think!