【问题标题】:SwiftUI inverse animation delay on removalSwiftUI 反向动画延迟移除
【发布时间】:2020-06-01 21:40:47
【问题描述】:

我正在尝试在 SwiftUI 中编排动画。我希望两个彩色条在它们之间有延迟移入视图,然后在切换延迟的情况下移出视图,以便删除与插入相反。

我想我明白为什么下面的代码不起作用,但我不知道如何让它做我需要的:

import SwiftUI

struct TestAnimControl: View {
    @State var show: Bool = false
    @State var reverseDelay: Bool = false

    var body: some View {
        VStack {
            Button(action:{
                self.show.toggle()
            }) {
                Text("Animate")
                    .font(.largeTitle)
            }
            if show {
                Rectangle()
                    .foregroundColor(.blue)
                    .frame(height: 100)
                    .transition(.move(edge: .trailing))
                    .animation(Animation.spring().delay(show ? 0.3 : 0.5))
                Rectangle()
                    .foregroundColor(.red)
                    .frame(height: 100)
                    .transition(.move(edge: .trailing))
                    .animation(Animation.spring().delay(show ? 0.5 : 0.3))
            }
        }
    }
}

当你运行这个并点击按钮时,蓝条移入,然后红条移入。再次点击按钮,蓝条移出,然后红条移出。我想要的是当你点击删除按钮时,红色条移出,然后蓝色条移出,与条进入的方式相反。在这段代码中,我相信三元组不起作用,因为设置了动画当创建 Rectangle 并且之后延迟不能改变。我可能错了,但无论哪种方式都有办法做我想做的事吗?

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    这里有一个解决方案。使用 Xcode 11.4 / iOS 13.4 测试

    struct TestAnimControl: View {
        @State var show: Bool = false
        @State var reverseDelay: Bool = false
    
        @State var blueDelay = 0.3
        @State var redDelay = 0.5
        var body: some View {
            VStack {
                Button(action:{
                    self.show.toggle()
                }) {
                    Text("Animate")
                        .font(.largeTitle)
                }
                if show {
                    Rectangle()
                        .foregroundColor(.blue)
                        .frame(height: 100)
                        .transition(.move(edge: .trailing))
                        .animation(Animation.spring().delay(blueDelay))//(show ? 0.3 : 0.5))
                        .onAppear { self.blueDelay = 0.5 }
                        .onDisappear { self.blueDelay = 0.3 }
                    Rectangle()
                        .foregroundColor(.red)
                        .frame(height: 100)
                        .transition(.move(edge: .trailing))
                        .animation(Animation.spring().delay(redDelay))//(show ? 0.5 : 0.3))
                        .onAppear { self.redDelay = 0.3 }
                        .onDisappear { self.redDelay = 0.5 }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您不能根据状态值更改delay 值,因为Animation 结构被标记为@frozen,这对属性观察者没有影响 - 状态属性(请查看https://docs.swift.org/swift-book/ReferenceManual/Attributes.html)。正确的做法是使用DispatchQueue.main.asyncAfter(deadline:_:) 指定每个延迟。这是我的示例代码...

      struct ContentView: View {
          @State var blue = false
          @State var red = false
      
          var body: some View {
              VStack {
                  Button(action:{
                      let redDelay = self.red ? 0.3 : 0.5
                      DispatchQueue.main.asyncAfter(deadline: .now() + redDelay) {
                          self.red.toggle()
                      }
                      let blueDelay = self.blue ? 0.5 : 0.3
                      DispatchQueue.main.asyncAfter(deadline: .now() + blueDelay) {
                          self.blue.toggle()
                      }
                  }) {
                      Text("Animate")
                          .font(.largeTitle)
                  }
                  if blue {
                      Rectangle()
                          .foregroundColor(.blue)
                          .frame(height: 100)
                          .transition(AnyTransition.move(edge: .trailing))
                          .animation(Animation.spring())
                  }
                  if red {
                      Rectangle()
                          .foregroundColor(.red)
                          .frame(height: 100)
                          .transition(AnyTransition.move(edge: .trailing))
                          .animation(Animation.spring())
                  }
              }
              .animation(.spring())
          }
      }
      

      谢谢。 X_X

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-10
        相关资源
        最近更新 更多