skip to Main Content

Is there a way to conditionally blur a view in SwiftUI?

For example for VStack:

VStack {
    //contents
}.blur(radius: 20)

Would blur the view. However, I’d like to blur it based on a condition.

I could use an if statement but that would mean writing the view twice in code like so:

if(shouldBlur)
{
    VStack {
        //contents
    }.blur(radius: 20)
}
else 
{
    VStack {
        //contents
    }
}

Is this the only way to achieve the desired outcome?

3

Answers


  1. There are a few different methods you could use. Methods 2 and 3 involve some duplication, but you can abstract that out of your direct view hierarchy.

    struct ContentView: View {
        @State private var isBlurred = false
        
        var body: some View {
            VStack {
                Button("Toggle") { isBlurred.toggle() }
                
                Text("Sample 1").blur(radius: isBlurred ? 20 : 0)
                Text("Sample 2").modifier(ConditionalBlurred(isBlurred: isBlurred, radius: 20))
                Text("Sample 3").conditionalBlur(isBlurred: isBlurred, radius: 20)
            }
        }
    }
    
    struct ConditionalBlurred: ViewModifier {
        var isBlurred: Bool
        var radius: CGFloat
        
        func body(content: Content) -> some View {
            if isBlurred {
                content.blur(radius: radius)
            } else {
                content
            }
        }
    }
    
    extension View {
        @ViewBuilder func conditionalBlur(isBlurred: Bool, radius: CGFloat) -> some View {
            if isBlurred {
                self.blur(radius: radius)
            } else {
                self
            }
        }
    }
    
    Login or Signup to reply.
  2. We can just use 0 (no blur), like

    VStack {
        //contents
    }.blur(radius: shouldBlur ? 20 : 0)     // << here !!
    
    Login or Signup to reply.
  3. You can just store Views in variables, like so:

    var viewToBlur: some View = {
    //your View
    }
    

    And then use the same View twice in your body, like so:

    if(shouldBlur)
    {
        VStack {
            viewToBlur
        }.blur(radius: 20)
    }
    else 
    {
        VStack {
            viewToBlur
        }
    }
    

    And if your View needs dynamic properties you can use functions that return AnyView, like so:

    func viewToBlur() -> AnyView{
     return AnyView(
    //your View
    )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search