MultiDatePicker y ShareLink en SwiftUI 4
MultiDatePicker y ShareLink en SwiftUI 4

MultidatePicker y ShareLink en SwiftUI #WWDC22

MultiDatePicker y ShareLink son dos nuevas vistas añadidas a SwiftUI 4. La primera nos permite seleccionar varias fechas de un calendario y la segunda nos permite compartir una URL (con información) a nuestros amigos, ShareLink muestra las apps donde queremos compartir.

SwiftBeta

Tabla de contenido

Aprende a usar MultiDatePicker y ShareLink en SwiftUI 4

Hoy en SwiftBeta vamos a ver dos nuevas vistas añadidas durante la #WWDC22. Las vistas son MultiDatePicker y ShareLink, ahora con iOS 16 podemos seleccionar multiples fecha de un calendario y también podemos abrir la vista de Share para compartir información de nuestra app hacía otra que tenga instalada el user. En el ejemplo de hoy, seleccionaremos varias fechas y dejaremos que un user pueda compartir esa información por un iMessage.

Si quieres apoyar al canal, puedes suscribirte, de esta manera seguiré subiendo contenido semanal sobre Swift, SwiftUI, Xcode y mucho más.

Aquí podrás encontrar todos los cambios introducidos en SwiftUI

Apple Developer Documentation

Creamos el proyecto con Xcode 14

Como siempre vamos a crear un proyecto de cero para probar estas dos nuevas vistas. Acuerdate de seleccionar SwiftUI cuando crees el proyecto, ya que es el framework que vamos a utilizar.

MultiDatePicker en SwiftUI

Lo primero de todo que vamos hacer es añadir una nueva vista que nos permite seleccionar multiples fechas. Al utilizar el inicializador, nos aparece un primer parámetro de tipo Binding<Set<DateComponents>>. Vamos a crear una propiedad de tipo Set<DateComponents>:

struct ContentView: View {
    @State var selectedDates: Set<DateComponents> = []
    
    var body: some View {
        MultiDatePicker(selection: $selectedDates) {
            Label("Escoge una fecha",
                  systemImage: "calendar.badge.plus")
        }
        .frame(height: 200)
    }
}

Al compilar vemos que podemos seleccionar múltiples fechas, pero quizás nos interesa tener una restricción de que solo se puedan seleccionar fechas a partir de una fecha. Vamos a escoger que solo se puedan escoger fechas para seleccionar en el futuro. Tan solo tenemos que utilizar uno de los inicializadores de MultiDatePicker:

struct ContentView: View {
    @State var selectedDates: Set<DateComponents> = []
    
    var body: some View {
        MultiDatePicker(selection: $selectedDates, in: .now...) {
            Label("Escoge una fecha",
                  systemImage: "calendar.badge.plus")
        }
        .frame(height: 200)
    }
}

Fíjate que ahora al compilar no podemos seleccionar fechas anteriores al día actual.

Lo siguiente que vamos hacer es mostrar las fechas que está seleccionando un user, y crearemos un ShareLink para que pueda compartir esas fechas con sus amigos.

Antes de utilizar la vista ShareLink, vamos a mostrar las fechas seleccionadas en un Text, para ello tendremos que aplicar un formatter, vas a ver lo sencillo que es:

struct ContentView: View {
    @State var finalDates: String = ""
    @State var selectedDates: Set<DateComponents> = []
    
    var body: some View {
        Form {
            MultiDatePicker(selection: $selectedDates, in: .now...) {
                Label("Escoge una fecha",
                      systemImage: "calendar.badge.plus")
            }
            Text(finalDates)
            Button("Aceptar") {
                getDatesFormatted()
            }
        }
    }
    
    func getDatesFormatted() {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd/MM/YY"

        let dates = selectedDates
            .compactMap { Calendar.current.date(from: $0) }
            .map { formatter.string(from: $0 )}
        finalDates = dates.joined(separator: "\n")
    }
}

Si compilamos nuestra app, podemos ver que podemos seleccionar varias fechas, y que cuando le damos al button de Aceptar, aparecen dentro del Text. Esta info es la que vamos a utilizar para compartir con ShareLink. Pero antes comentarte que podemos mejorar nuestro código, si queremos que al pulsar una fecha se vea automáticamente reflejado en la variable finalDates, podemos utilizar el modificador onChange. Es decir, podríamos añadir el siguiente código:

.onChange(of: selectedDates) { _ in
     getDatesFormatted()
 }

Vamos a añadir ShareLink justo abajo de nuestra vista, para hacerlo vamos a añadir ShareLink fuera del Form. Al abrir paréntesis vemos los diferentes inicializadores, escogemos el que tiene un item, subject, y message.

struct ContentView: View {
    @State var finalDates: String = ""
    @State var selectedDates: Set<DateComponents> = []
    @State var url = URL(string: "https://www.swiftbeta.com")!
    
    var body: some View {
        Form {
            MultiDatePicker(selection: $selectedDates, in: .now...) {
                Label("Escoge una fecha",
                      systemImage: "calendar.badge.plus")
            }
            Text(finalDates)
            Button("Aceptar") {
                getDatesFormatted()
            }
        }
        ShareLink("¡Suscríbete a SwiftBeta! 🎉",
                  item: url,
                  subject: Text("Fechas de los próximos videos"),
                  message: Text(finalDates))
    }
	//...
}

Si compilamos nuestra app y seleccionamos varias fechas, vemos como al apretar el Button de ShareLink aparece la vista de share donde podemos seleccionar qué aplicaciones usar para compartir la información de nuestra app.

Conclusión

Hoy hemos aprendido a usar dos nuevas vistas MultiDatePicker y ShareLink en iOS 16. Está claro que Apple está haciendo que con muy pocas líneas de código podamos tener componentes muy completos, si esta es la dinámica de Apple, veremos lo sencillo que es crear apps a medida que SwiftUI evolucione.

Si quieres seguir aprendiendo sobre SwiftUI, Swift, Xcode, o cualquier tema relacionado con el ecosistema Apple