带有 TextView 的 RectangleView 在 3 秒内滑入屏幕,但滑动时 TextView 的状态在一秒后发生了变化。现在可以看到 TextView 停止滑动,立即跳转到目的地。
我只想在滑动时将 RectangleView 与 TextView 视为一个整体,并且在状态改变时不要改变 TextView 的位置,无论它旋转或保持静止。
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")
}
}
}
}
答案 0 :(得分:1)
它因为视图被重新创建使用延迟。删除 DispatchQueue.main.asyncAfter
还使用一个单一的 bool var 进行动画。两者都不需要。
struct ContentView: View {
@State private var go = false
@State private var rotation = false
var body: some View {
VStack {
Button("Go!") {
go.toggle()
rotation.toggle() //<-- Here
}
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.delay(1.0), value: animationRotating) //<-- here
.onAppear { animationRotating = true }
.onDisappear { animationRotating = false }
} else {
Text("S")
}
}
}
}
编辑:
您也在更改带有动画的文本。为此,您需要更改您的正文代码。
@State private var opacity: Double = 1
var body: some View {
print("refresh, rotation = \(rotation)"); return
Text("R")
.foregroundColor(.blue)
.rotationEffect(.degrees(animationRotating ? 360 : 0))
.animation(animation.delay(1.0), value: animationRotating) //<-- here
.opacity(!animationRotating ? opacity : 0)
.onAppear {
animationRotating = true
opacity = 1
}
.onDisappear {
animationRotating = false
opacity = 0
}
.overlay(Text("S")
.opacity(animationRotating ? opacity : 0))
.frame(minWidth: 0, maxWidth: .infinity, alignment: .trailing)
}