在 SwiftUI 中,如何在显示时为按钮偏移设置动画

In SwiftUI how can I animate a button offset when displayed

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

我试过:

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

但没有快乐。

如果您想尝试偏移,这可以帮助您入门。

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)),但我正在更新我的答案。除非你的按钮在屏幕的边界上,否则它可能不太合适。移动仅限于移动视图的大小。所以你可能最终需要使用偏移量!

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

首先你需要创建一个转换。您可以为 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 布尔值(随便命名),它将处理按钮的显示。这将使用 @State 属性 包装器,因此 SwiftUI 将在更改时刷新 UI。

@State var showButton: Bool = false;

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

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

最后,您可以在动画块中将 showButton 布尔值更新为 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

的内容

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

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()
        }
    }
}

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

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)