SwiftUI: dynamiczna zmiana przejścia widoku po utworzeniu widoku
Chcę dynamicznie zmienić przejście widoku po utworzeniu widoku. Przełączam zmienną stanu isTransition1, klikając przycisk, aby przełączać się między transition1i transition2jak poniżej. Jednak nie działa zgodnie z przeznaczeniem, jeśli jednym z tych przejść jest krycie. Widok, który ma zostać usunięty natychmiast po zmianie przejścia, zawsze zachowuje oryginalne przejście. O dziwo, jeśli przestawię się transition2na suwak, będzie działać bez problemu. Widok, który ma zostać usunięty, użyje nowego przejścia. Czy jest jakiś sposób, aby krycie działało tutaj?
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)
}
}
}
}
}
Odpowiedzi
Nie jestem pewien, czy dobrze zrozumiałem, jaki efekt próbowałeś osiągnąć, ale spróbuj zresetować hierarchię widoków (przynajmniej to zdecydowanie resetuje przejścia, więc nie wpływają na siebie):
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 !!
}