【问题标题】:In SwiftUI how can I animate a button offset when displayed在 SwiftUI 中,如何在显示时为按钮偏移设置动画
【发布时间】:2019-06-21 17:23:06
【问题描述】:

在 SwiftUI 中,我希望在最初显示视图时通过从顶部进入最终位置来从屏幕外显示一个按钮,当按下按钮时我不要求动画。

我试过了:

Button(action: {}) {
    Text("Button")
}.offset(x: 0.0, y: 100.0).animation(.basic(duration: 5))

但没有快乐。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    如果你想玩偏移,这可以让你开始。

    struct ContentView : View {
        @State private var offset: Length = 0
    
        var body: some View {
            Button(action: {}) { Text("Button") }
                .offset(x: 0.0, y: offset)
                .onAppear {
                    withAnimation(.basic(duration: 5)) { self.offset = 100.0 }
                }
        }
    }
    

    我首先建议使用 .transition(.move(.top)),但我正在更新我的答案。除非您的按钮位于屏幕边框上,否则它可能不太适合。移动仅限于移动视图的大小。所以你可能需要使用偏移量!

    注意,要使其开始远离屏幕,偏移量的初始值可以为负数。

    【讨论】:

      【解决方案2】:

      首先,您需要创建一个过渡。您可以为AnyTransition 创建一个扩展名,或者只创建一个变量。使用move() 修饰符来告诉转换将视图从特定边缘移入

      let transition = AnyTransition.move(edge: .top);
      

      仅当视图位于屏幕边缘时才有效。如果您的视图更靠近中心,您可以使用 combined() 修饰符来组合另一个过渡,例如 offset() 以添加额外的偏移量

      let transition = AnyTransition
          .move(edge: .top)
          .combined(with:
              .offset(
                  .init(width: 0, height: 100)
              )
          );
      

      虽然您可以使用AnyTransition.asymmetric() 来使用不同的过渡来显示和删除视图,但此过渡将用于显示和删除视图

      接下来创建一个showButton bool(随便命名),它将处理显示按钮。这将使用 @State 属性包装器,因此 SwiftUI 将在更改时刷新 UI。

      @State var showButton: Bool = false;
      

      接下来,您需要将转换添加到您的按钮,并将您的按钮包装在 if 语句中,检查 showButton 布尔值是否为 true

      if (self.showButton == true) {
          Button(action: { }) {
              Text("Button")
          }
          .transition(transition);
      }
      

      最后,您可以在动画块中将 showButton bool 更新为 truefalse 以动画按钮转换。 toggle() 只是反转 bool 的状态

      withAnimation {
          self.showButton.toggle();
      }
      

      您可以将代码放入onAppear() 并将布尔值设置为true,以便在视图出现时显示按钮。您可以在大多数情况下致电onAppear(),例如VStack

      .onAppear {
          withAnimation {
              self.showButton = true;
          }
      }
      

      查看 Apple 文档以查看适用于 AnyTransition https://developer.apple.com/documentation/swiftui/anytransition 的内容

      【讨论】:

      • 有帮助!但是为什么要分号呢?
      • 有帮助!但为什么是括号? -> if (self.showButton == true)
      • @Jessy 这只是一个偏好
      • @PeterKreinz 这只是一个偏好
      【解决方案3】:

      在顶部显示一个带有动画的消息框:

      import SwiftUI
      
      struct MessageView: View {
          @State private var offset: CGFloat = -200.0
          var body: some View {
              VStack {
                  HStack(alignment: .center) {
                      Spacer()
                      Text("Some message")
                          .foregroundColor(Color.white)
                          .font(Font.system(.headline).bold())
                      Spacer()
                  }.frame(height: 100)
                      .background(Color.gray.opacity(0.3))
                      .offset(x: 0.0, y: self.offset)
                      .onAppear {
                          withAnimation(.easeOut(duration: 1.5)) { self.offset = 000.0
                          }
                  }
                  Spacer()
              }
          }
      }
      

      【讨论】:

      • 这最终会为整个视图设置动画,而不仅仅是消息视图
      【解决方案4】:

      对于那些想要从点击时移动的按钮开始的人,试试这个:

      import SwiftUI
      
      struct ContentView : View {
          @State private var xLoc: CGFloat = 0
      
          var body: some View {
              Button("Tap me") {
                  withAnimation(.linear(duration: 2)) { self.xLoc+=50.0 }
              }.offset(x: xLoc, y: 0.0)
          }
      
      }
      

      或者(可以用任何东西替换文本):

              Button(action: { 
                  withAnimation(.linear(duration: 2)) { self.xLoc+=50.0 } 
                  } )
              { Text("Tap me") }.offset(x: xLoc, y: 0.0)
      

      【讨论】:

        猜你喜欢
        • 2020-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多