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

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/


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
}

-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)

.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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.