【问题标题】:How can I animate SwiftUI state changes from specific values to new state values?如何将 SwiftUI 状态从特定值更改为新状态值设置动画?
【发布时间】:2021-08-14 00:31:45
【问题描述】:

我有一个矩形视图,当位置状态发生变化时,我会为该位置设置动画。这会隐式地从原始点动画到新的状态值。

@State var position: (Double, Double)

GeometryReader { geo in
  Rectangle()
      .fill(Color.red)
      .frame(width: 200, height: 200)
      .position(x: geo.size.width * CGFloat(position.0), y: geo.size.height * CGFloat(position.1))
}

如何在每次位置状态更改时从特定位置设置动画。例如,我想从 (0.5, 0.5) 而不是原始位置动画到新位置状态。这将使视图出现在 (0.5, 0.5) 位置,然后动画到新的位置状态。

这是默认动画

这是我要应用的动画

【问题讨论】:

  • 你不能把你已经拥有的位置改为你想要的初始值,然后用动画块来改变它吗?你有预期结果的 gif 图像吗? position = (1,1); withAnimation { position = (0.1,0.1) } 老实说,这似乎是一个简陋的动画,但我可以看到一些用途。
  • @Gry 我添加了一些显示默认和预期动画的 gif

标签: swift xcode swiftui swiftui-animation


【解决方案1】:

这是我希望您需要的示例,在 move function 中我添加了开始和结束位置更改状态逻辑。

我重命名并更新了位置类型,因为如果您在 View 函数中使用“位置”名称,swiftui 已经保留了它。 var animate state 大部分时间都不需要,它的功能是禁用动画以在所需的动画偏移量上移动矩形,但只是在你想同时链接多个更改位置的情况下,否则你可以删除它。

您可以根据需要测试更改fromto 值。

struct ExampleView: View {
    @State var positionPoint: CGPoint = CGPoint.init(x: 0.5, y: 0.5)
    @State var animate: Bool = false

    var body: some View {
        ZStack {
            GeometryReader { geo in
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 200, height: 200)
                    .position(x: geo.size.width * positionPoint.x,
                              y: geo.size.height * positionPoint.y)
                    .animation(animate ? .easeIn : nil)
            }
            
            VStack(spacing: 10) { // some test button
                Button(action: {
                    move(from: (0.2, 0.7), to: (0.8, 0.3))
                }, label: {
                    Text("from: (0.2, 0.7), to: (0.8, 0.3)")
                })
                Button(action: {
                    move(from: (1, 1), to: (0.1, 0.1))
                }, label: {
                    Text("from: (1, 1), to: (0.1, 0.1)")
                })
                Button(action: {
                    move(from: (0.6, 0.6), to: (0.5, 0.9))
                }, label: {
                    Text("from: (0.6, 0.6), to: (0.5, 0.9)")
                })
                Button(action: {
                    move(from: (0.8, 0.1), to: (0.3, 1))
                }, label: {
                    Text("from: (0.8, 0.1), to: (0.3, 1)")
                })
            }
        }
    }
    
    func move(from: (CGFloat, CGFloat), to: (CGFloat, CGFloat)) {
        animate = false
        positionPoint = CGPoint.init(x: from.0, y: from.1)
        withAnimation {
            animate = true
            positionPoint = CGPoint.init(x: to.0, y: to.1)
        }
    }

}

【讨论】:

  • 我测试了 ExampleView,但它们从“从”点移动到“到”点。我想从示例 (0.5, 0.5) 动画到“到”点。视图已经在一个设定的位置,但我希望它跳到 (0.5, 0.5) 然后从那里开始动画
  • 嗯,如果你想从 0.5,0.5 到“到”点。您可以像这样设置移动功能。 move(from: (0.5, 0.5), to: (0.3, 1))。它总是从中间跳。如果它不是您搜索的内容,抱歉,但恐怕我现在不知道您需要什么。每当我点击示例视图中的 4 个按钮时,它们会跳转到 from 位置,即 (0.2,0.7 - 1,1 - 0.6,0.6 - 0.8,0.1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 2021-09-15
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多