Wie deaktiviere ich die Animation in der Liste, wenn sich beobachtete Objekte in SwiftUI ändern?

15

Wie deaktiviere ich die Animation, wenn sich die Modelldaten ändern?

Ich habe folgenden Code:

struct FormView: View {

    @ObservedObject var viewModel: FormViewModel

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

Jedes Mal, wenn Änderungen am Ansichtsmodell Listmit einer Animation aktualisiert werden.
Wie kann ich es deaktivieren?
Ich habe versucht hinzuzufügen, .animation(nil)aber es hilft nicht

0rt
quelle

Antworten:

1

Die Problemumgehung, bis Apple uns eine Änderung für List gibt, lautet List.id (_ :). Sie ändert den internen Status von List und erzwingt, dass die Liste ohne Animation sofort neu erstellt wird. Weitere Informationen finden Sie unter Auflisten von Animationsfehlern

Das Gleiche kann für jede Ansicht durchgeführt werden (func id () ist Teil des View-Protokolls), aber Sie müssen wissen, dass alle Statusvariablen den anfänglichen "Standard" -Status haben. Verwenden Sie ihn daher vorsichtig. Es ist dasselbe wie das "Neuerstellen" der Ansicht.

Informationen zur Funktionsweise finden Sie unter https://swiftui-lab.com/swiftui-id/.

user3441734
quelle
1

Die Lösung, die ich gefunden habe, besteht darin, eine eindeutige Kennung hinzuzufügen, die sich jedes Mal ändert, sodass die Liste jedes Mal ohne Animation neu erstellt wird. Verifiziert unter iOS 13.4.

var body: some View {
    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }
    }
    .id(UUID()) // no animation
}
Burgler-dev
quelle
-3
  1. Es ist nicht erforderlich, ForEach innerhalb der Liste zu verwenden, falls Sie keine verwenden Section. Also statt:

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

    Der folgende Code reicht zum Schreiben aus:

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

    Und besser zu wissen, dass die Verwendung von ForEach einige Probleme verursachen kann, wie zum Beispiel: SwiftUI: Ist es möglich, ForEach + ContextMenu zu verwenden?

  2. Im Falle von verwenden Sie nur ForEach()oder nur List()+ .animation(nil)- muss Ihr Problem lösen:

    Probe 1:

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

    Probe 2:

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

    Ich wurde sowohl unter macOS 10.15.2 (19C57) getestet als auch es funktioniert perfekt.

  3. Sie können auch versuchen, .animation(nil)auf Listund ForEachbeides zu verwenden. Ich habe es nicht versucht ... aber ich denke, das wird dir auch den nötigen Effekt geben.

    List {
        ForEach(viewModel.options) { option in
            Text(option.displayValue)
        }.animation(nil)
    }.animation(nil)
Andrew
quelle
.animation(nil)scheint leider keine Auswirkung auf 13.3 zu haben
Fabian Streitel
@FabianStreitel Ich habe Teil 2 unter macOS 10.15.2 (19C57) getestet und es funktioniert perfekt.
Andrew
Und ich habe alle drei Varianten unter iOS 13.3 getestet (wie in meinem obigen Kommentar angegeben) und keine von ihnen ändert das Listenverhalten überhaupt. OP hat leider nicht angegeben, ob sie eine iOS- oder eine MacOS-App erstellen. Aber ich denke, die Information, dass es unter iOS nicht funktioniert, ist auch für andere relevant.
Fabian Streitel
Ich habe kürzlich .animation(nil)mit Xcode 11.4 mit iOS 13.4 getestet und es funktioniert für mich.
Simen