Qué es Picker
El componente Picker permite al usuario seleccionar un valor entre un listado de opciones definido. Es un componente equivalente a UIPickerView y UISegmentedControl de UIKit.
Aquí podéis consultar la documentación oficial
La creación del componente se puede realizar de varias formas:
struct ContentView: View {
let items = ["Sevilla", "Cádiz", "Huelva", "Córdoba", "Málaga", "Granada", "Jaén", "Álmería"]
@State private var selection: String = "Sevilla"
var body: some View {
Picker("Select one option", selection: $selection) {
ForEach(items, id: .self) {
Text("($0)")
.foregroundColor(.blue)
}
}
}
}
Esteinit consta de los siguientes parámetros:
String: texto a mostrar para introducir alPicker. En este ejemplo no se verá, ya que se usa en casos específicos como cuando lo incluimos en unNavigationView→Form.selection: variable de estado con la selección actual delPicker.content: es el listado de opciones que se presentarán en el picker.
También disponemos de otro init que nos da el mismo resultado:
struct ContentView: View {
let items = ["Sevilla", "Cádiz", "Huelva", "Córdoba", "Málaga", "Granada", "Jaén", "Álmería"]
@State private var selection: String = "Sevilla"
var body: some View {
Picker(selection: $selection, label: Text("Select one option")) {
ForEach(items, id: .self) {
Text("($0)")
.foregroundColor(.blue)
}
}
}
}
En este caso tenemos los siguientes parámetros:
selection: variable de estado con la selección actual delPicker.label:Viewa mostrar para introducir alPicker. En este ejemplo no se verá, ya que se usa en casos específicos como cuando lo incluimos en unNavigationView→Form.content: es el listado de opciones que se presentarán en el picker.
Nota: el parámetro selection es una variable de estado que usará el componente Picker para asignar el valor seleccionado. Cuando queremos usar un valor fijo (por ejemplo, por motivos de pruebas) podemos usar la función .constant() que pertenece al struct Binding para cumplir con su implementación sin tener que declarar la variable de estado.
Cómo cargar y leer datos de un Picker
Para poder saber qué opción es la que está seleccionada en un Picker tenemos que crear una relación entre los datos cargados y la variable selection.
La carga de datos de un Picker se realizará normalmente a través del componente ForEach, iterando sobre un listado de elementos. En este punto lo importante es que cada elemento del ForEach sea único porque implementa el protocolo Identifiable o porque lo especificamos explicitamente en el ForEach (cómo cuando cargamos un listado de String e indicamos id: .self).
Al realizar la carga de esta forma el Picker es capaz de identificar cada elemento de forma única y lo que hace es volcar la selección actual en la variable selection que recibe en su init. Por este motivo, la variable selection deberá ser del mismo tipo que el id que usamos en el ForEach. Para una lista de String la variable de estado será String y tiene que tener uno de los valores preseleccionados (no puede ser opcional ?).
let items = ["Sevilla", "Cádiz", "Huelva", "Córdoba", "Málaga", "Granada", "Jaén", "Álmería"] @State private var selection: String = "Sevilla"
En los ejemplos anteriores esta variable es de tipo String porque el id del ForEach es la misma variable sobre la que se itera (un String), pero puede ser cualquier otro tipo:
struct ContentView: View {
@State private var selection: Flavor = Flavor.chocolate
var body: some View {
VStack {
Picker(selection: $selection, label: Text("Select one option")) {
ForEach(Flavor.allCases, id: .self) {
Text("($0.rawValue)")
.foregroundColor(.orange)
}
}
Text("Selection: (selection.rawValue)")
}
}
enum Flavor: String, CaseIterable, Identifiable {
case chocolate = "Chocolate"
case vanilla = "Vanilla"
case strawberry = "Strawberry"
var id: String { self.rawValue }
}
Modificadores comunes para Picker
El componente Picker comparte los mismos métodos de personalización que el componente View, y pueden ser consultados en el siguiente enlace.
pickerStyle
Permite alternar entre diferentes modos de presentación del Picker. El parámetro debe implementar el protocolo PickerStyle.
struct ContentView: View {
@State private var selection: Flavor = Flavor.chocolate
var body: some View {
ScrollView {
VStack {
Group {
Picker("Select one option", selection: $selection1) {
ForEach(Flavor.allCases, id: .self) {
Text("($0.rawValue)")
.foregroundColor(.blue)
}
}
.pickerStyle(WheelPickerStyle())
Text("Selection: (selection1.rawValue)")
}
}
}
.padding()
}
enum Flavor: String, CaseIterable, Identifiable {
case chocolate = "Chocolate"
case vanilla = "Vanilla"
case strawberry = "Strawberry"
var id: String { self.rawValue }
}
}
Para iOS existen diferentes implementaciones:
WheelPickerStyle
Este tipo es equivalente a UIPickerView de UIKit. Es el tipo por defecto.
.pickerStyle(WheelPickerStyle())
SegmentedPickerStyle
Este tipo es equivalente a UISegmentedControl de UIKit.
.pickerStyle(SegmentedPickerStyle())
MenuPickerStyle (iOS 14)
.pickerStyle(MenuPickerStyle())
InlinePickerStyle (iOS 14)
.pickerStyle(InlinePickerStyle())
Ejemplo
Puedes encontrar este ejemplo en github.com bajo el apartado Picker.
Rafael Fernández,
iOS Tech Lider
Aeronautics