Animation 如何在SwiftUI中基于平移手势或滚动视图位置以交互方式切换视图?

Animation 如何在SwiftUI中基于平移手势或滚动视图位置以交互方式切换视图?,animation,swiftui,interactive,Animation,Swiftui,Interactive,在我构建的UIKit应用程序中,我曾经有过这样的效果,滚动视图可以通过使用UIPropertyImator并操纵其fractionComplete属性来控制启用/禁用视图中特定约束的动画。这允许动画跟随滚动视图的进度 在SwiftUI中,我不再控制约束,而是基于@State变量更改整个视图层次结构(例如,我要在两个状态之间转换的视图有一个名为isExpanded)的属性) 使用SwiftUI的withAnimation,只需切换所需的布尔值,即可轻松完成此简单转换。使用matchedGeomet

在我构建的UIKit应用程序中,我曾经有过这样的效果,滚动视图可以通过使用UIPropertyImator并操纵其
fractionComplete
属性来控制启用/禁用视图中特定约束的动画。这允许动画跟随滚动视图的进度

在SwiftUI中,我不再控制约束,而是基于
@State
变量更改整个视图层次结构(例如,我要在两个状态之间转换的视图有一个名为
isExpanded
)的属性)

使用SwiftUI的
withAnimation
,只需切换所需的布尔值,即可轻松完成此简单转换。使用
matchedGeometryEffect(id:in:properties:anchor:isSource:)
我可以轻松地让元素从/移动到正确的位置

我想弄清楚的是,我如何基本上暂停,然后控制动画的进程,以便通过平移手势控制开始和结束状态之间的转换,或者像我在UIKit中使用的那样,通过
滚动视图

下面是我的SwiftUI代码的一个基本示例:

struct MyTwoStatesView: View {
    
    @Namespace var namespace
    @State var isExpanded: Bool = true
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 4)
                .fill(Color.gray)
            if isExpanded {
                ExpandedStateView(namespace: namespace)
            }
            else {
                CollapsedStateView(namespace: namespace)
            }
        }
        .fixedSize(horizontal: false, vertical: true)
        .onTapGesture {
            withAnimation {
                isExpanded.toggle()
            }
        }
    }
}
以下是最终动画的效果:


以后编辑: 下面是“完整”示例的要点:

使用计时器

在平移手势开始时启动计时器

计时器运行时,检查或响应平移手势


获取平移手势的x和y坐标,以确定每次平移手势的速度,并使用该坐标确定每次动画进行时的增量

在平移手势结束或完全最大化或完全最小化时结束计时器

“现在是完全不同的事情。”

“添加评论”对我不起作用。我点击它,它会把我带到页面顶部,我无法输入任何文本

在我的帖子后面有一条评论说,
“每次动画进展的增量。”您如何控制这一点阿赫兹17分钟前 以下是答案,因为我无法使用添加评论:

让计时器运行,也许每1/100秒就可以得到平移手势的x和y坐标。如果手势移动缓慢,则以增量缓慢调整大小。调整大小至某个大小,尝试将原始开始手势的x和y保持在平移手势下

如果用户快速平移手势,则快速调整大小。如果它们的大小调整缓慢,并且需要整整一秒钟的时间才能完成手势,那么请将其大小调整为减去原始大小的1/100(或计时器设置的任何值)

“暂停”调整大小:如果用户做出部分平移的手势,那么在计时器运行时,它应该检测到平移手势已暂停,那么它没有输入来告诉它继续调整大小


我希望您理解这一点,因为在回答这个问题的时间结束之前,我可能不会回到这个问题。

您能显示
ExpandedStateView
CollapsedStateView
的代码吗(因此我们不需要重新创建布局)?我添加了一个包含完整布局示例的要点链接,尽管布局本身并不重要。基本上,我希望能够通过平移手势或滚动视图位置来控制交换动画。我认为您可以通过自己计算每个动画,并通过交互值(平移手势、滚动视图位置等)“每次动画进行时的增量”来更改视图位置和大小你是怎么控制的?我不知道我是否理解你的建议我做什么。。。例如,如何在中途“停止”动画?在
UIKit
中,使用
UIPropertyAnimator
交换约束,可以轻松暂停动画并指定
fractionComplete
以控制其进度。。我如何用你提到的计时器实现这一点?