DEV Community

GoyesDev
GoyesDev

Posted on

SwiftUI #30: Toggle (Interruptor)

Toggle es un control que puede conmutar entre dos estados que se pinta como un "switch" en iPhone y iPad, y como un "checkbox" en Mac.

  • init(_:ison:): Recible una etiqueta como primer argumento, y un binding que almacena el estado actual.
  • init(isOn:label:): Recibe un binding, y una "etiqueta" (vista) como un @ViewBuilder. Este closure puede incluir varias vistas como subtítulos de varios niveles.
struct ContentView: View {
  @State private var enabled = true
  var body: some View {
    Toggle(isOn: $enabled) {
      HStack {
        Image(systemName: "eye")
        Text("Enable/Disable")
      }
      Text("Subtítulo 1")
      Text("Subtítulo 2")
      Text("Subtítulo 3")
    }
    .padding()
  }
}
Enter fullscreen mode Exit fullscreen mode

El componente Toggle crea un stack horizontal que contiene la etiqueta y el interruptor con un espacio en la mitad. Como consecuencia, el componente ocupa todo el espacio horizontal disponible de su contenedor, y la etiqueta y el interruptor se dibujan en los extremos.

Ocultar la etiqueta

En caso de querer ocultar la etiqueta se puede usar el modificador labelsHidden().

Aplicar un estilo

Se puede cambiar el estilo del Toggle con toggleStyle(_:), que recibe una estructura que conforma el protocolo ToggleStyle, que tiene los valores estáticos automatic, button, checkbox y switch.

En caso de requerir algún estilo personalizado, hay que definir el método makeBody(configuration:), que define y retorna una vista que reemplaza el cuerpo del Toggle.

Tener en cuenta que al usar un ToggleStyle, seré responsable de la interacción del usuario y, por ende, de actualizar el estado del control. Por esta razón, debo aplicar un GestureRecognizer para cambiar el estado del binding.

struct MyStyle: ToggleStyle {
  func makeBody(configuration: Configuration) -> some View {
    HStack(alignment: .center) {
      configuration.label
      Spacer()
      Image(systemName: "checkmark.rectangle.fill")
        .font(.largeTitle)
        .foregroundStyle(configuration.isOn ? .green : .gray)
        .onTapGesture {
          configuration.isOn.toggle()
        }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
struct ContentView: View {
  @State private var enabled = true
  var body: some View {
    Toggle("Título simple", isOn: $enabled)
    .toggleStyle(MyStyle())
    .padding()
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)