【问题标题】:How to switch views in SwiftUI interactively based on a pan gesture or scroll view position?如何基于平移手势或滚动视图位置以交互方式切换 SwiftUI 中的视图?
【发布时间】:2021-07-14 09:09:42
【问题描述】:

在我构建的 UIKit 应用程序中,我曾经使用过这种效果,滚动视图将通过使用 UIPropertyAnimator 并操纵它的 fractionComplete 属性来控制启用/禁用视图中特定约束的动画。这允许动画跟随滚动视图的进展。

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

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

我想弄清楚的是我怎样才能基本上暂停然后控制动画的进程,以便通过平移手势控制我的开始和结束状态之间的转换,或者,比如我曾经在 UIKit 中通过 ScrollView 进行操作。

这是我的 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()
            }
        }
    }
}

这是最终动画的效果:


后期编辑: 这是“完整”示例的要点:https://gist.github.com/zeusent/39f58827519d9bfda63271a9cb24d6b6

【问题讨论】:

  • 您能否显示ExpandedStateViewCollapsedStateView 的代码(这样我们就不需要重新创建布局)?
  • 我添加了一个指向包含完整布局示例的要点的链接,即使布局本身并不重要。基本上我希望能够通过平移手势或滚动视图位置来控制交换动画。
  • 我认为您可以通过自己计算每个动画并通过交互值(平移手势、滚动视图位置...等)更改视图位置和大小来做到这一点

标签: animation swiftui interactive


【解决方案1】:

使用计时器。

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

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

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

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

“现在来点完全不同的东西。”

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

在我的帖子之后有一条评论说, “每次动画进展发生的增量。”你怎么控制这个呢? – aheze 17 分钟前 这是答案,因为我不能使用添加评论:

运行一个计时器,可能每 1/100 秒获取平移手势的 x 和 y 坐标。如果手势移动缓慢,则以增量缓慢调整大小。调整大小以尝试将原始开始手势的 x 和 y 保持在平移手势之下。

如果用户快速平移手势,则快速调整大小。如果他们缓慢调整大小,并且手势完成需要整整一秒钟,则将大小调整为原始大小的负 1/100(或您的计时器设置的任何值)。

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

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

【讨论】:

  • "每次动画进展发生的增量。"不过你是怎么控制的呢?
  • 我不确定我是否理解您的建议...例如,您如何“停止”动画中途?在UIKit 中使用UIPropertyAnimator 你可以交换约束并且可以轻松地暂停动画并指定fractionComplete 来控制它的进度。我如何使用你提到的计时器来实现这一点?
猜你喜欢
  • 1970-01-01
  • 2021-03-16
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多