How can I give a custom ButtonStyle in SwiftUI additional options

Viewed 256

I currently have a ButtonStyle defined as below:

struct RoundedButtonRed: ButtonStyle {
  func makeBody(configuration: Configuration) -> some View {
    HStack {
      Spacer()
      configuration.label.foregroundColor(.white)
      Spacer()
    }
    .padding()
    .background(Color.red.cornerRadius(13.0))
    .scaleEffect(configuration.isPressed ? 0.85 : 1)
  }
}

I also have another struct (RoundedButtonBlack) that has a .background(Color.black.cornerRadius(13.0)), which seems like unnecessary code duplication. Is there a way to add custom configuration options so that I can use the same struct for different colors?

e.g.

struct RoundedButtonRed: ButtonStyle {
  func makeBody(configuration: Configuration) -> some View {
    HStack {
      Spacer()
      configuration.label.foregroundColor(.white)
      Spacer()
    }
    .padding()
    .background(configuration.backgroundColor) // background color taken from configuration or passed into .buttonStyle(RoundedButton()) call
    .scaleEffect(configuration.isPressed ? 0.85 : 1)
  }
}

Or, perhaps there is a better way altogether?

1 Answers

Just add a property inside your RoundedButton struct that stores a color. Then, when you apply it with buttonStyle, you can pass in any color you want.

struct RoundedButton: ButtonStyle {
    var color: Color /// add property here
    
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            Spacer()
            configuration.label.foregroundColor(.white)
            Spacer()
        }
        .padding()  /// use it here
        .background(color.cornerRadius(13.0))
        .scaleEffect(configuration.isPressed ? 0.85 : 1)
    }
}

struct ContentView: View {
    var body: some View {
        VStack {                                                     /// pass it in here
            Button("Red button") {}.buttonStyle(RoundedButton(color: .red))
            Button("Black button") {}.buttonStyle(RoundedButton(color: .black))
        }
    }
}

Result:

Red button on top of black button

Related