¿Cómo deshabilitar la animación en la lista cuando los objetos observados cambian en SwiftUI?


15

¿Cómo desactivo la animación cuando veo cambios en los datos del modelo?

Tengo el siguiente código:

struct FormView: View {

    @ObservedObject var viewModel: FormViewModel

    var body: some View {
        List {
            ForEach(viewModel.options) { option in
                Text(option.displayValue)
            }
        }
    }
}

Cada vez que los cambios en el modelo de vista Listse actualizan con animación.
¿Cómo puedo desactivarlo?
Traté de agregar .animation(nil)pero no ayuda

Respuestas:


1

La solución hasta que Apple nos dé un cambio para hacerlo en la Lista es llamar a List.id (_ :) Cambia el estado interno de la Lista y obliga a la Lista a recrearse inmediatamente, sin ninguna animación. Para más detalles, vea Lista de fallas de animación de recarga

Lo mismo podría hacerse en cualquier Vista (la función func id () es parte del protocolo de Vista), pero debe saber que todas las variables de estado tendrán un estado inicial "predeterminado", así que úselo con cuidado. Es lo mismo que "recrear" la Vista.

Para poder entender cómo funciona, consulte https://swiftui-lab.com/swiftui-id/


1

La solución que encontré es agregar un identificador único que cambia cada vez, por lo que reconstruirá la lista cada vez sin animación. Verificado en iOS 13.4.

var body: some View {
    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }
    }
    .id(UUID()) // no animation
}

-3
  1. No es necesario usar ForEach dentro de List en caso de que no use Section's. Entonces en lugar de:

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        })
    }

    El siguiente código es suficiente para escribir:

    List(viewModel.options) { option in
        Text(option.displayValue)
    }

    Y también es mejor saber que el uso de ForEach puede crear algunos problemas, por ejemplo: SwiftUI: ¿es posible usar ForEach + ContextMenu?

  2. En caso de que use solo ForEach()o solo List()+ .animation(nil)- debe resolver su problema:

    Muestra 1:

    ForEach(viewModel.options) { option in
        Text(option.displayValue)
    }.animation(nil)

    Muestra 2:

    List(viewModel.options) { option in
        Text(option.displayValue)
    }.animation(nil)

    He sido probado tanto en macOS 10.15.2 (19C57) y funciona perfectamente.

  3. También puede intentar usar .animation(nil)en Listy ForEachambos. No lo intenté ... pero creo que esto también le dará el efecto necesario.

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }.animation(nil)
    }.animation(nil)

.animation(nil)parece no tener efecto en 13.3, desafortunadamente
Fabian Streitel

@FabianStreitel He probado la parte 2 en macOS 10.15.2 (19C57) y funciona perfectamente.
Andrew

Y he estado probando las tres variantes en iOS 13.3 (como se indicó en mi comentario anterior) y ninguna de ellas cambia el comportamiento de la Lista. OP no dijo si están haciendo una aplicación iOS o macOS, desafortunadamente. Pero creo que la información de que no funciona en iOS también es relevante para otros.
Fabian Streitel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.