Abhi Ram
Abhi Ram

Reputation: 53

How to blur background when another view is active?

I have tried blurring the first VStack when a view from the second one is active. But when doing so, the "Enable Blur" Button's background colour changes every time it is tapped. I am not sure where I'm going wrong here and would like to know if there's a better way to do this.

struct ContentView: View {
    
    @State private var showWindow = false
    var body: some View {
        ZStack{
            VStack{
                Button(action: {self.showWindow.toggle()}){
                    Text("Enable Blur")
                        .foregroundColor(.white)
                        .padding()
                        .background(Color.black)
                        .cornerRadius(5)
                }
            }.blur(radius: showWindow ? 5 : 0)
            VStack{
                if(showWindow){
                    DatePickerView(showWindow: self.$showWindow)
                }
            }
        }
    }
}

struct DatePickerView: View {
    @Binding var showWindow: Bool
    var body: some View{
        VStack{
            Button(action: {self.showWindow.toggle()}){
                Text("Done").foregroundColor(.white)
            }
        }
    }
}

Upvotes: 2

Views: 248

Answers (1)

Asperi
Asperi

Reputation: 257563

The blur effect accumulates because VStack content is not determined as changed by SwiftUI rendering engine, so its cached rendered variant is used to next redraw.. and so on.

To fix this we need to mark VStack to refresh. Here is possible solution. Tested with Xcode 11.4 / iOS 13.4

VStack{
    Button(action: {self.showWindow.toggle()}){
        Text("Enable Blur")
            .foregroundColor(.white)
            .padding()
            .background(Color.black)
            .cornerRadius(5)
    }
}.id(showWindow)                  // << here !!
.blur(radius: showWindow ? 5 : 0)

Upvotes: 2

Related Questions