SwiftUI: How to add a border to text in if conditions are met?

Viewed 1862

I know I can use something like:

Text("Hello World")
 .overlay(
   RoundedRectangle(cornerRadius: 10)
      .stroke(Color.black, lineWidth:1)
)

to add a border around a Text View, but how can I add it based on a true/false value? Say I want to have a button that when pushed adds a border around text, how can I implement the overlay to only appear if a var is true?

3 Answers

The most easier and correct way for this work is here:

If your variable for showing Border is true it would work, otherwise it would apply nothing!


enter image description here


import SwiftUI

struct ContentView: View {
    
    @State private var addBorder: Bool = false
    
    var body: some View {
        
        Text("Hello, world!")
            .padding()
            .overlay(addBorder ? RoundedRectangle(cornerRadius: 10).stroke(Color.black, lineWidth:1) : nil)
        
        Button("add Border") { addBorder.toggle() }
            .padding()
        
    }
}

one simple way is this:

@State var wantBorder = false
...
Text("Hello World")
 .overlay(
  RoundedRectangle(cornerRadius: 10)
  .stroke(wantBorder ? Color.black : Color.clear, lineWidth:1)
)

If the event you're talking about a Button, you'd probably want to use a custom ButtonStyle so that you can react to the state of the press:

struct ContentView: View {
    var body: some View {
        Button(action: {}) {
            Text("Hello World")
        }
        .buttonStyle(CustomButtonStyle())
    }
}

struct CustomButtonStyle : ButtonStyle {
    
    @ViewBuilder func makeBody(configuration: Configuration) -> some View {
        if configuration.isPressed {
            configuration.label
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                       .stroke(Color.black, lineWidth:1)
               )
        } else {
            configuration.label
        }
    }
    
}

In a non-button situation, You can use a ternary expression and provide nil if the condition isn't true:

struct ContentView: View {
    @State var showOverlay = false
    
    var body: some View {
        Button(action: { showOverlay.toggle() }) {
            Text("Hello World")
                .overlay(
                    showOverlay ?
                    RoundedRectangle(cornerRadius: 10)
                       .stroke(Color.black, lineWidth:1)
                    : nil)
        }
    }
}

Finally, one relatively-clean way to do this would be to use a view modifier:

struct ContentView: View {
    @State var showOverlay = false
    
    var body: some View {
        VStack(spacing: 10) {
            Button("Toogle") {
                showOverlay.toggle()
            }
            Text("Hello World").modifier(OverlayModifier(showOverlay: showOverlay))
        }
    }
}

struct OverlayModifier : ViewModifier {
    var showOverlay : Bool
    
    @ViewBuilder func body(content: Content) -> some View {
        if showOverlay {
            content
                .overlay(
                    RoundedRectangle(cornerRadius: 10)
                       .stroke(Color.black, lineWidth:1)
               )
        } else {
            content
        }
    }
}
Related