Reputation: 425
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
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
Reputation: 257543
We can just use 0
(no blur), like
VStack {
//contents
}.blur(radius: shouldBlur ? 20 : 0) // << here !!
Upvotes: 4
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