SwiftUI – Cómo mostrar un Popover

Qué es un Popover

Los popover son un tipo de vista muy útil en iOS para presentar información relativa a otra vista o acción. Podríamos decir que el popover es una ventana emergente en la que podemos cargar una vista personalizada. Esta ventana se mostrará haciendo referencia a otra vista, de modo que indicará visualmente sobre quien afecta las acciones realizadas en ella. El sistema se encargará de modificar la visualización dependiendo del contexto donde se cree.

En SwiftUI no existe un componente popover como tal pero podemos conseguir este comportamiento a través del modificador popover presente en el protocolo View. Esto sería equivalente a usar el componente UIPopoverPresentationController de UIKit. Puedes consultar aquí la documentación oficial.

Para presentar el componente se usa el siguiente modificador sobre el View que deba presentarlo:

@State private var showPopover = false

...

.popover(isPresented: $showPopover) {
    //Your View here
}

El modificador popover tiene otros parámetros para personalizar la dirección desde donde se debe mostrar el propio popover, pero si no se indica el sistema se encargará de tomar la decisión. En el ViewBuilder del popover debemos crear la vista que necesitemos mostrar.

Para presentar el popover tenemos que crearnos una variable de estado que deberemos indicar en el parámetro isPresented. De esta forma el componente se mostrará cuando sea true y estará oculto cuando sea false.

Un ejemplo completo sería así:

struct ContentView: View {
    let itemsPicker = ["Sevilla", "Cádiz", "Huelva", "Córdoba", "Málaga", "Granada", "Jaén", "Álmería"]
    
    @State private var textFieldSelection: String = ""
    @State private var pickerSelection: String = "Sevilla"
    @State private var sliderSelection: Double = 50
    @State private var colorSelection: Color = .red
    @State private var datePickerSelection: Date = Date()
    @State private var toggleSelection: Bool = true
    
    @State private var showPopover = false
    @State private var buttonPressed: String?
    
    var body: some View {
        VStack(spacing: 15) {
            Button("Show Popover") {
                showPopover.toggle()
            }
            if let buttonPressed = buttonPressed {
                Text("You pressed "(buttonPressed)" button")
            }
            
        }
        .popover(isPresented: $showPopover) {
            NavigationView {
                Form {
                    Section(header: Text("First section")) {
                        Text("Hello, World!")
                        TextField("Select text", text: $textFieldSelection)
                        Slider(value: $sliderSelection, in: 0...100)
                        Picker("Select province", selection: $pickerSelection) {
                            ForEach(itemsPicker, id: .self) {
                                Text($0)
                            }
                        }.navigationBarTitleDisplayMode(.inline)
                    }
                    Section(header: Text("Second section")) {
                        ColorPicker("Select Color", selection: $colorSelection)
                        DatePicker("Select date", selection: $datePickerSelection)
                        Toggle("Enabled", isOn: $toggleSelection)
                        Button("Done") {
                            //Do something
                        }
                        .disabled(!toggleSelection)
                    }
                    .listRowBackground(Color.yellow.opacity(0.3))
                    
                    Section() {
                        HStack {
                            Text("Version")
                            Spacer()
                            Text("1.0.0")
                        }
                    }
                }
            }
            .frame(idealWidth: 400, maxWidth: .infinity, idealHeight: 600, maxHeight: .infinity)
        }
    }
}

Ejemplo

Puedes encontrar este ejemplo en nuestro perfil de Github bajo el apartado Popover.

Rafael Fernández,
iOS Tech Lider