Como desativar a animação na lista quando o objeto observado é alterado no SwiftUI?

15

Como desabilito a animação ao visualizar alterações nos dados do modelo?

Eu tenho o seguinte código:

struct FormView: View {

    @ObservedObject var viewModel: FormViewModel

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

Toda vez que as alterações no modelo de exibição Listsão atualizadas com animação.
Como posso desabilitá-lo?
Eu tentei adicionar, .animation(nil)mas não ajuda

0rt
fonte

Respostas:

1

A solução alternativa até que a Apple nos altere para fazer isso na Lista é chamada List.id (_ :) Altera o estado interno da Lista e força a Lista a recriar imediatamente, sem nenhuma animação. Para detalhes, consulte Listar recargas de falhas de animação

O mesmo poderia ser feito em qualquer View (func id () faz parte do protocolo View), mas você precisa saber que todas as variáveis ​​de estado terão o estado "padrão" inicial, portanto, use-o com cuidado. É o mesmo que "recriar" a exibição.

Para entender como funciona, consulte https://swiftui-lab.com/swiftui-id/

user3441734
fonte
1

A solução que encontrei é adicionar um identificador exclusivo que muda sempre, para reconstruir a lista todas as vezes sem animação. Verificado no iOS 13.4.

var body: some View {
    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }
    }
    .id(UUID()) // no animation
}
Burgler-dev
fonte
-3
  1. Não é necessário usar o ForEach dentro da Lista, caso você não os utilize Section. Então, em vez de:

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

    O código a seguir é suficiente para escrever:

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

    E também é melhor saber que o uso do ForEach pode criar alguns problemas, como por exemplo: SwiftUI: é possível usar o ForEach + ContextMenu?

  2. No caso de você usar apenas ForEach()ou apenas List()+ .animation(nil)- deve resolver seu problema:

    Amostra 1:

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

    Amostra 2:

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

    Fui testado no macOS 10.15.2 (19C57) e funciona perfeitamente.

  3. Além disso, você pode tentar usar .animation(nil)em Liste ForEachtanto. Eu não tentei ... mas acho que isso também dará o efeito necessário.

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }.animation(nil)
    }.animation(nil)
Andrew
fonte
.animation(nil)parece não ter efeito em 13.3, infelizmente #
Fabian Streitel 26/12/19
@FabianStreitel Fui testado na parte 2 no macOS 10.15.2 (19C57) e funciona perfeitamente.
27519 Andrew Andrew
E eu tenho testado todas as três variantes no iOS 13.3 (como afirmado no meu comentário acima) e nenhuma delas altera o comportamento da lista. O OP não afirmou se está criando um aplicativo para iOS ou macOS, infelizmente. Mas acho que as informações de que não funcionam no iOS também são relevantes para os outros.
Fabian Streitel
Testei recentemente .animation(nil)usando o Xcode 11.4 com iOS 13.4 e funciona para mim.
Simen 15/04