DEV Community

GoyesDev
GoyesDev

Posted on

[SUI] Transición de tipo Zoom

Para definir una animación de tipo Zoom se debe definir:

  1. ¿Qué vista se va a presentar con Zoom? / Para esto se aplica el modificador navigationTransition(_:), con el argumento zoom(sourceID:in:), sobre la vista que se va a presentar, que recibe un sourceID que es el "id" de la vista de origen y un namespace.
  2. ¿Cuál es la vista de origen? / Para esto se usa matchedTransitionSource(id:in:) sobre la vista que origina la transición, que recibe el "id" de la vista de origen y un namespace.
  3. Un @Namespace donde se relacionan el origen y destino de la transición (que es una especie de Binding).
struct DetailView: View {
  let person: Person

  var body: some View {
    VStack {
      Text("Esta es la vista detalle para el siguiente personaje:")
      Text("\(person.name) \(person.lastname)")
    }
    .navigationTitle("Detalle")
    .navigationBarTitleDisplayMode(.inline)
  }
}
Enter fullscreen mode Exit fullscreen mode
struct ContentView: View {

  @State private var searchText: String = ""
  @State private var navigationPath = NavigationPath()
  // ⚠️ Este es el namespace que va a conectar el zoom
  @Namespace private var personNamespace

  private var filteredPeople: [Person] {
    if searchText.isEmpty {
      people
    } else {
      people.filter {
        $0.name.localizedStandardContains(searchText) }
    }
  }

  var body: some View {
    NavigationStack(path: $navigationPath) {
      List(filteredPeople) { person in
        NavigationLink(value: person) {
          // ⚠️ Se aplica matchedTransitionSource a la vista
          // de origen con el id de la persona
          Label("\(person.name) \(person.lastname)", systemImage: "person")
            .matchedTransitionSource(id: person.id, in: personNamespace)
        }
      }
      .navigationDestination(for: Person.self, destination: { person in
        // ⚠️ Se aplica navigationTransition(.zoom(...)) a la
        // vista que se va a presentar, a partir del id de la 
        // vista de origen.
        // ⚠️ Extrañamente no funciona el autocompletar con 
        // .zoom así que igual hay que escribirlo.
        DetailView(person: person)
          .navigationTransition(.zoom(sourceID: person.id, in: personNamespace))
      })
      .navigationTitle("Personas")
      .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .automatic), prompt: "¿A quién busca?")
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Bibliografía

Top comments (0)