1
votes

Créer une transition dont la suppression dépend d'une valeur @State lorsque la vue est supprimée

Je voudrais créer une transition dont la suppression dépend d'une valeur @State lorsque la vue est supprimée.

Voici ce que j'ai essayé.

Si isValid est vrai lorsque la vue apparaît, il utilisera .move (edge: .trailing) pour la suppression, même si isValid devient faux entre-temps .

Ce que j'essaie d'obtenir est une transition .move (edge: .leading) si isValid est false lorsque le la vue est supprimée, même si elle était true lorsque la vue a été insérée.

Le problème apparaît lorsque je bascule show et isValid code> en même temps.

struct TextTransitionView: View {
    @State var isValid = false
    @State var show = false

    var body: some View {
        VStack {
            Spacer()

            if show {
                Text("TEXT").transition(slideTransition)
            }

            Spacer()

            Text("Move to \(isValid ? "right" : "left")")

            Button("Toggle isValid") {
                self.isValid.toggle()
            }

            Button("Toggle show") {
                withAnimation { self.show.toggle() }
            }

            Button("Toggle isValid and show") {
                withAnimation {
                    self.isValid.toggle()
                    self.show.toggle()
                }
            }
        }
    }

    var slideTransition: AnyTransition {
        let removal = isValid ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading)
        return .asymmetric(insertion: .identity, removal: removal)
    }
}


0 commentaires

3 Réponses :


1
votes

Voici une approche possible. Testé avec Xcode 11.4 / iOS 13.4

 démo

struct DemoTextTransition: View {
    @State var isValid = false
    @State var show = false
    var body: some View {
        VStack {
            if show {
                Text("TEXT").transition(slideTransition)
            }
            Button("Valid: \(isValid ? "True" : "False")") {
                self.isValid.toggle()
            }
            Button("Test") {
                withAnimation { self.show.toggle() }
            }
        }
    }

    var slideTransition: AnyTransition {
        let removal = isValid ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading)
        return .asymmetric(insertion: .identity, removal: removal)
    }
}


1 commentaires

Merci pour votre réponse. Quand je l'ai lu, j'ai pensé que c'était exactement ce que je faisais. En fait, cela m'a aidé à identifier le vrai problème. J'ai édité ma question pour ajouter un code complet avec le bogue et posté une réponse pour le résoudre.



0
votes

voulez-vous dire comme ça?

struct ContentView: View {

    @State var isValid = false

    var slideTransition: AnyTransition {
        let removal = isValid ? AnyTransition.move(edge: .trailing) : AnyTransition.move(edge: .leading)
        return .asymmetric(insertion: .identity, removal: removal)
    }

    var body: some View {
        VStack {
            Button(action: {
                withAnimation() {
                    self.isValid.toggle()
                }
            }) {
                Text("animate it")
            }
            if isValid {
                Text("text").transition(slideTransition)
            }
        }
    }
}


0 commentaires

0
votes

Le problème était que isValid.toggle () se trouvait dans le withAnimation . La sortie de cette ligne du bloc withAnimation a résolu le problème.

Button("Toggle isValid and show") {
    self.isValid.toggle()
    withAnimation {
        self.show.toggle()
    }
}


0 commentaires