在 SwiftUI 中,如何在显示时对按钮偏移量进行动画处理

In SwiftUI how can I animate a button offset when displayed

提问人:J. Edgell 提问时间:6/22/2019 更新时间:2/12/2022 访问量:17790

问:

在 SwiftUI 中,我希望在最初显示视图时从顶部放到最终位置,从而从屏幕外显示一个按钮,而不是在按下按钮时要求动画。

我试过了:

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

但没有喜悦。

SWIFTUI的

评论


答:

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

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

8赞 Liam 6/22/2019 #2

首先,您需要创建一个过渡。您可以为变量创建扩展,也可以只创建一个变量。使用修饰符告诉过渡从特定边向内移动视图AnyTransitionmove()

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

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

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

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

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

@State var showButton: Bool = false;

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

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

最后,您可以将 bool 更新到动画块中或动画块内,以动画化按钮过渡。 只是颠倒了布尔的状态showButtontruefalsetoggle()

withAnimation {
    self.showButton.toggle();
}

您可以输入代码并将 bool 设置为,以便在视图出现时显示按钮。您可以调用大多数东西,例如onAppear()trueonAppear()VStack

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

查看 Apple 文档,了解可供 https://developer.apple.com/documentation/swiftui/anytransition 使用的内容AnyTransition

评论

3赞 7/14/2020
有益的!但为什么是分号呢?
1赞 Peter Kreinz 5/21/2021
有益的!但为什么是括号呢?-> if (self.showButton == true)
1赞 Liam 5/22/2021
@Jessy 这只是一种偏好
1赞 Liam 5/22/2021
@PeterKreinz 这只是一种偏好
3赞 Javier Calatrava Llavería 4/23/2020 #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()
        }
    }
}

评论

0赞 masaldana2 8/29/2021
这最终会对整个视图进行动画处理,而不仅仅是消息视图
1赞 mrzzmr 2/11/2022 #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)