Reading time: 1 min

This recipe shows how to implement a custom Toggle via ToggleStyle. The particular ToggleStyle you'll implement will make a Toggle look like a checkbox. The end result will look like this:

Screenshot%202021-08-10%20at%2017.01.08

OK, here's the code for the custom ToggleStyle. It maps the ToggleStyleConfiguration onto a custom view that represents a checkbox. It also allows for a custom parameter to choose if the checkbox will be circular or square-shaped:

struct CheckboxToggleStyle: ToggleStyle {
  @Environment(\.isEnabled) var isEnabled
  let style: Style // custom param

  func makeBody(configuration: Configuration) -> some View {
    Button(action: {
      configuration.isOn.toggle() // toggle the state binding
    }, label: {
      HStack {
        Image(systemName: configuration.isOn ? "checkmark.\(style.sfSymbolName).fill" : style.sfSymbolName)
          .imageScale(.large)
        configuration.label
      }
    })
    .buttonStyle(PlainButtonStyle()) // remove any implicit styling from the button
    .disabled(!isEnabled)
  }

  enum Style {
    case square, circle

    var sfSymbolName: String {
      switch self {
      case .square:
        return "square"
      case .circle:
        return "circle"
      }
    }
  }
}

Then, you can simply use it like this:

Toggle("Checkbox 1", isOn: $isOn1)
  .toggleStyle(CheckboxToggleStyle(style: .square))
  .foregroundColor(.blue)

Toggle("Checkbox 2", isOn: $isOn2)
  .toggleStyle(CheckboxToggleStyle(style: .circle))
  .foregroundColor(.red)

Next Post Previous Post