Oftentimes I get to a situation where I need to apply a View Modifier only if a certain condition is met. Achieving this - surprisingly - is not so easy in SwiftUI. Fortunately, we can make it much easier with one simple View extension.

Imagine a screen like this...

We have two Buttons and one Text view. We want to apply a background color and padding to the Text in order to create a highlight effect as the buttons are pressed.

There are of course multiple solution to this problem but I find the simple View extension below quite elegant.

extension View {
    @ViewBuilder
    func `if`<Content: View>(_ condition: Bool, content: (Self) -> Content) -> some View {
        if condition {
            content(self)
        }
        else {
            self
        }
    }
}

This extension defines one function on all Views that:

  • Is a View builder so that type-erasure using AnyView or other workarounds like using Group or TupleView are not necessary in its body.
  • Accepts a boolean parameter to indicate whether the next closure should be applied.
  • Accepts a closure that users must provide to conditionally apply View modifiers to the View.

Using this View extension the code for our screen is very simple...

struct TestView: View {
    @State var isHighlighted = false
    @State var isPadded = false
    
    var body: some View {
        VStack(spacing: 16) {
            Text("Lorem ipsum dolor sit amet")
                .if(isPadded) { view in
                    view.padding()
                }
                .if(isHighlighted) { view in
                    view.background(Color.yellow)
                }
            
            VStack {
                Button(action: { self.isHighlighted.toggle() }) {
                    Text("Toggle highlight")
                }
                
                Button(action: { self.isPadded.toggle() }) {
                    Text("Toggle padding")
                }
            }
        }
    }
}

That's it! Fortunately, Swift makes adding functionality like this to existing code very easy.

I hope that you'll find this simple extension helpful!