'swiftui, animation applied to parent effect child animation(Part II)
PREVIOUS Q: swiftui, animation applied to parent effect child animation
Now the TextView has its own state. RectangleView with TextView slide into screen in 3 seconds, but state of TextView changed after a second while sliding. Now you can see TextView stops sliding, go to the destination at once. I Just want RectangleView with TextView as a whole when sliding, and TextView rotates or keeps still as I want.
import SwiftUI
struct RotationEnvironmentKey: EnvironmentKey {
static let defaultValue: Bool = false
}
extension EnvironmentValues {
var rotation: Bool {
get { return self[RotationEnvironmentKey] }
set { self[RotationEnvironmentKey] = newValue }
}
}
struct AnimationTestView: View {
@State private var go = false
@State private var rotation = false
var body: some View {
VStack {
Button("Go!") {
go.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
rotation.toggle()
print("set rotation = \(rotation)")
}
}
Group {
if go {
RectangleView()
.transition(.slide)
.environment(\.rotation, rotation)
}
}.animation(.easeInOut(duration: 3.0), value: go)
}.navigationTitle("Animation Test")
}
}
struct RectangleView: View {
var body: some View {
Rectangle()
.frame(width: 200, height: 100)
.foregroundColor(.pink)
.overlay(TextView())
}
}
struct TextView: View {
@Environment(\.rotation) var rotation
@State private var animationRotating: Bool = false
let animation = Animation.linear(duration: 3.0).repeatForever(autoreverses: false)
var body: some View {
print("refresh, rotation = \(rotation)"); return
HStack {
Spacer()
if rotation {
Text("R")
.foregroundColor(.blue)
.rotationEffect(.degrees(animationRotating ? 360 : 0))
.animation(animation, value: animationRotating)
.onAppear { animationRotating = true }
.onDisappear { animationRotating = false }
} else {
Text("S")
}
}
}
}
Solution 1:[1]
I found the issue here: cannot use if cause in TextView, because when rotation changed, will create a new Text in new position, so we can see the R 'jump' to the right position.
code as following:
Text(rotation ? "R" : "S")
.foregroundColor(rotation ? .blue : .white)
.rotationEffect(.degrees(animationRotating ? 360 : 0))
.animation(rotation ? animation : nil, value: animationRotating)
.onChange(of: rotation) { newValue in
animationRotating = true
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | foolbear |