有没有办法知道是哪个状态更改导致视图在SwiftUI中重建?

有没有办法知道是哪个状态更改导致视图在SwiftUI中重建?,swift,animation,swiftui,gesture,Swift,Animation,Swiftui,Gesture,我有一个视图需要像手风琴一样工作,用户可以通过拖动来打开/折叠它。我希望它在用户拖动时没有任何动画,而是在用户离开时进行动画。所以,我想在我的视图中有两个状态变量(例如,height和tempHeight),但我只会在height变量触发视图重建过程时设置动画 拖动时,在“高度”和“tempHeight”更改上设置动画看起来很奇怪,感觉有延迟 描述我的问题的示例代码: struct ContentView: View { @State var tempHeight: CGFloat =

我有一个视图需要像手风琴一样工作,用户可以通过拖动来打开/折叠它。我希望它在用户拖动时没有任何动画,而是在用户离开时进行动画。所以,我想在我的视图中有两个状态变量(例如,height和tempHeight),但我只会在height变量触发视图重建过程时设置动画

拖动时,在“高度”和“tempHeight”更改上设置动画看起来很奇怪,感觉有延迟

描述我的问题的示例代码:

struct ContentView: View {
    @State var tempHeight: CGFloat = 200
    @State var height: CGFloat = 200
    var dragGesture: some Gesture {
        
        DragGesture(),
            .onChanged { value in
                
                tempHeight = min(400, max(200, height + value.translation.height))
            }
            .onEnded { value in
                
                height = tempHeight > 300 ? 400 : 200
                tempHeight = height
            }
    }
    
    var body: some View {
        VStack {
            Spacer()
                .frame(height: 100)
            Color.blue.frame(height: tempHeight)
                .animation(.easeIn)
                .gesture(dragGesture)
            Spacer()
        }
    }
}
我试图解决这个问题的方法是使用一个静态变量,它跟踪最后发生的状态变化,并且似乎有效。 我当前的解决方法:

enum StateChange {
    case height
    case tempHeight
    
    static var lastChangeBy: StateChange = .height
}

struct ContentView: View {
    @State var tempHeight: CGFloat = 200
    @State var height: CGFloat = 200
    
    var dragGesture: some Gesture {
        
        DragGesture()
            .onChanged { value in
                
                tempHeight = min(400, max(200, height + value.translation.height))
                StateChange.lastChangeBy = .tempHeight
            }
            .onEnded { value in
                
                height = tempHeight > 300 ? 400 : 200
                tempHeight = height
                StateChange.lastChangeBy = .height
                
            }
    }
    
    var body: some View {
        VStack {
            Spacer()
                .frame(height: 100)
            Color.blue.frame(height: tempHeight)
                .gesture(dragGesture)
                .animation(StateChange.lastChangeBy == .height ? .easeInOut : .none)
                .animation(.easeInOut)
            Spacer()
        }
    }
}

对我来说,这感觉像是一种恶作剧。如果我有很多@State包装的变量,它很快就会变得一团糟。是否可以知道哪个状态更改触发在身体内部构建视图,以便我可以有条件地将动画应用于特定的触发器或更好的编写方式。

您可以明确指定哪些值更改在修改器中激活动画,如

  Color.blue.frame(height: tempHeight)
        .gesture(dragGesture)
        .animation(.easeInOut, value: height)   // << here
Color.blue.frame(高度:tempHeight)
.手势(德拉格斯特尔)
.animation(.easeInOut,值:高度)//