SwiftUI : modifier dynamiquement la transition d'une vue après la création de la vue
Je souhaite modifier dynamiquement la transition d'une vue après la création de la vue. Je bascule une variable d'état isTransition1
en cliquant sur un bouton pour basculer entre transition1
et transition2
comme ci-dessous. Cependant, cela ne fonctionne pas comme prévu si l'une de ces transitions est l'opacité. La vue à supprimer immédiatement après le changement de transition conserve toujours sa transition d'origine. Étonnamment, si je change transition2
pour glisser, cela fonctionnera sans problème. La vue à supprimer utilisera la nouvelle transition. Existe-t-il un moyen de faire fonctionner l'opacité ici?
let transition1 = AnyTransition.asymmetric(insertion: .move(edge: .trailing),
removal: .move(edge: .leading))
let transition2 = AnyTransition.opacity
struct Wrapper1<Content: View>: View {
let content: Content
var body: some View {
content
}
}
struct Wrapper2<Content: View>: View {
let content: Content
var body: some View {
content
}
}
struct TextView: View {
let count: Int
let color: Color
var body: some View {
ZStack {
color
.edgesIgnoringSafeArea(.all)
.frame(maxWidth: UIScreen.main.bounds.width,
maxHeight: UIScreen.main.bounds.height)
Text("Count: \(count)")
.font(.title)
.offset(y: -200)
}
}
}
struct ContentView: View {
@State private var count = 0
@State private var isTransition1 = false
var body: some View {
ZStack {
if count % 2 == 0 {
Wrapper1(content: TextView(count: count, color: Color.green)
.transition(isTransition1 ? transition1 : transition2))
} else {
Wrapper2(content: TextView(count: count, color: Color.red)
.transition(isTransition1 ? transition1 : transition2))
}
HStack(spacing: 100) {
Button(action: {
self.isTransition1.toggle()
}) {
Text("Toggle Transition").font(.title)
}
Button(action: {
withAnimation(.linear(duration: 2)) {
self.count += 1
}
}) {
Text("Increase").font(.title)
}
}
}
}
}
Réponses
Je ne sais pas si j'ai bien compris l'effet que vous avez essayé d'obtenir, mais essayez de réinitialiser la hiérarchie des vues (au moins, cela réinitialise définitivement les transitions, afin qu'elles ne s'affectent pas):
var body: some View {
ZStack {
if count % 2 == 0 {
Wrapper1(content: TextView(count: count, color: Color.green)
.transition(isTransition1 ? transition1 : transition2))
} else {
Wrapper2(content: TextView(count: count, color: Color.red)
.transition(isTransition1 ? transition1 : transition2))
}
HStack(spacing: 100) {
Button(action: {
self.isTransition1.toggle()
}) {
Text("Toggle Transition").font(.title)
}
Button(action: {
withAnimation(.linear(duration: 2)) {
self.count += 1
}
}) {
Text("Increase").font(.title)
}
}
}.id(isTransition1) // << here !!
}