我不知道为什么我的动画过渡在我的情况下不起作用。我有一个登录视图和一个主视图,当我按下一个按钮时,我想平滑地过渡到另一个视图。下面是我使用的代码。
我在这里错过了什么?**
非常感谢!
import SwiftUI
class AppState: ObservableObject {
@Published var loginScreen: Bool
init(loginScreen: Bool) {
self.loginScreen = loginScreen
}
}
@main
struct Test: App {
@StateObject var appState: AppState = AppState(loginScreen: true)
var body: some Scene {
WindowGroup {
if appState.loginScreen {
LoginView()
.environmentObject(appState)
} else {
MainView()
.environmentObject(appState)
}
}
}
}
登录视图:
import SwiftUI
struct LoginView: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
HStack {
LogInButton().environmentObject(appState)
}.padding()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let appState = AppState(loginScreen: true)
LoginView().environmentObject(appState)
}
}
下面是我的按钮登录视图:
import SwiftUI
struct LogInButton: View {
@EnvironmentObject var appState: AppState
var body: some View {
Button(action: {
appState.loginScreen.toggle()
}) {
HStack {
Text("Log In")
}
}
}
}
struct LogInButton_Previews: PreviewProvider {
static var previews: some View {
let appState = AppState(loginScreen: true)
LogInButton().environmentObject(appState)
}
}
以及主视图:
import SwiftUI
struct MainView: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
Spacer()
Button("Go to login") {
appState.loginScreen.toggle()
}
.font(.title)
}
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
1条答案
按热度按时间20jt8wwn1#
主要是,没有动画,因为你没有指定。当你点击一个按钮来切换应用状态的布尔值时,这会触发SwiftUI重建它的视图布局,并且它会尽可能快地完成。
一种控制更改动画方式的方法是向
LoginView
和MainView
的条件调用添加过渡修饰符。为了使这更容易,我将该条件移动到Scene
声明之外:(快速说明:如果你在层次结构的顶部声明了一个
.environmentObject
,你通常不需要在视图树的更下面重新声明它; SwiftUI会自动为你传递环境变量。您只在需要响应对象更改而更改的视图中选择@EnvironmentObject
)。另一种选择是将登录屏幕设置为
fullScreenCover
,它将自动动画以覆盖任何其他视图,并且通过绑定到布尔值来管理:您可以通过将
appState.loginScreen
的值更改为false来关闭login视图(就像您的代码当前所做的那样)。这是更干净的,你依靠的SwiftUI基础是相当健壮的。但是,您在如何呈现动画方面没有任何真实的的灵活性:登录屏幕将总是从底部边缘动画显示。但这是iOS用户熟悉的风格,所以可能没问题。