Jasjeev
Jasjeev

Reputation: 425

Blur a view in SwiftUI based on condition

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?

Upvotes: 1

Views: 1130

Answers (3)

Ratramnus
Ratramnus

Reputation: 21

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
)
}

Upvotes: 1

Asperi
Asperi

Reputation: 257543

We can just use 0 (no blur), like

VStack {
    //contents
}.blur(radius: shouldBlur ? 20 : 0)     // << here !!

Upvotes: 4

jnpdx
jnpdx

Reputation: 52347

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
        }
    }
}

Upvotes: 1

Related Questions