Animation SwiftUI:状态更改时,带动画的视图跳转到目标

Animation SwiftUI:状态更改时,带动画的视图跳转到目标,animation,swiftui,Animation,Swiftui,带TextView的矩形视图在3秒钟内滑入屏幕,但在滑动一秒钟后TextView的状态发生变化。现在您可以看到TextView停止滑动,立即跳转到目的地 我只想在滑动时将矩形视图与TextView作为一个整体,并且不改变TextView的位置,无论它在状态改变时旋转或保持静止 它因为视图被重新创建而使用延迟。删除DispatchQueue.main.asyncAfter还可以为动画使用一个bool变量。两者都不需要 struct ContentView: View { @State p

带TextView的矩形视图在3秒钟内滑入屏幕,但在滑动一秒钟后TextView的状态发生变化。现在您可以看到TextView停止滑动,立即跳转到目的地

我只想在滑动时将矩形视图与TextView作为一个整体,并且不改变TextView的位置,无论它在状态改变时旋转或保持静止


它因为视图被重新创建而使用延迟。删除
DispatchQueue.main.asyncAfter
还可以为动画使用一个bool变量。两者都不需要

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")
            }
        }
    }
}

struct ContentView:View{
@国家私有变量go=false
@状态私有变量旋转=false
var body:一些观点{
VStack{
按钮(“开始!”){
go.toggle()

rotation.toggle()//谢谢,但你误解了我的意思。使用DispatchQueue.main.asyncAfter只是模拟状态更改。我不知道旋转是什么时候发生的,只是在滑动时发生的。外部发布者导致旋转状态更改。它不是设计的。所以我的回答代码中是否缺少任何内容?我的意思是滑动时发生了一些事情,导致TextView需要旋转。在t他的时间,TextView立即跳转到目的地(参见GIF),但我不想要这个,我想要TextView滑动和旋转。如何修复它?好的,你想要滑动和旋转同时进行。我是对的吗?是的,我想要TextView与Rectangleview冻结位置,而不是分开。
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)
    }