【问题标题】:How to present a view full-screen in SwiftUI?如何在 SwiftUI 中全屏显示视图?
【发布时间】:2019-10-26 17:15:01
【问题描述】:

我曾经登录view,现在我想在登录后显示view,但我不希望用户有可能返回登录view。在UIkit 中我使用了present(),但似乎在SwiftUI presentation(_ modal: Modal?)view 并没有占据整个屏幕。 Navigation 也不是一个选项。

谢谢!

【问题讨论】:

  • 我认为苹果删除了功能介绍(....)

标签: ios view uikit swiftui


【解决方案1】:

我不希望用户有可能返回登录视图

在这种情况下,您不应该离开登录视图,而是完全替换它。

您可以通过有条件地构建登录视图或“应用程序视图”来做到这一点。

这样的……

// create the full screen login view
struct LoginView: View {
    // ...
}

//create the full screen app veiw
struct AppView: View {
    // ...
}

// create the view that swaps between them
struct StartView: View {
    @EnvironmentObject var isLoggedIn: Bool // you might not want to use this specifically.

    var body: some View {
        isLoggedIn ? AppView() : LoginView()
    }
}

通过使用这样的模式,您不会呈现或离开登录视图,而是完全替换它,因此它根本不再位于视图层次结构中。

这可确保用户无法导航回登录屏幕。

同样...通过像这样使用@EnvironmentObject,您可以稍后对其进行编辑(退出),您的应用将自动返回登录屏幕。

【讨论】:

  • 听起来不错,但我还有一个问题:在 LoginView 的模型中,我从服务器获取了一些我在 AppView 中需要的数据,如何将这些数据传输到 AppView?
  • @SorinLica 这就是 EnvironmentObject 的用途。我承认我还不完全了解如何使用 EnvironmentObject 的东西,但这就是它的用途。例如,您可能希望在其中保存您的用户信息。然后使用 EnvironmentObject 的任何东西都可以访问该信息,并且视图将在更改时更新。看看这个谈话...developer.apple.com/wwdc19/226
  • 鉴于某些 View 无法解析为类型,这是否还能编译?
  • 是的,因为你什么时候可以返回两种不同类型中的一种......这会出错
  • 我收到了来自编译器的“无法将'AppView'类型的返回表达式转换为'某些视图'类型”的消息。
【解决方案2】:
struct ContentView: View {
    @EnvironmentObject var userAuth: UserAuth 
    var body: some View {
        if !userAuth.isLoggedin {
            return AnyView(LoginView())
        } else {
            return AnyView(HomeView())
        }
    }
}

【讨论】:

  • 您好,欢迎来到 StackOverflow。发布答案很好,但解释它如何解决问题更好。
【解决方案3】:

将正文封装在一个组中以消除编译器错误:

struct StartView: View {

@EnvironmentObject var userAuth: UserAuth

var body: some View {
    Group {
        if userAuth.isLoggedin {
            AppView()
        } else {
            LoginView()
        }

    }
}

【讨论】:

    【解决方案4】:

    我为自己做了这个扩展。欢迎任何反馈/想法。 :)

    https://github.com/klemenkosir/SwiftUI-FullModal

    用法

    struct ContentView: View {
    
        @State var isPresented: Bool = false
    
        var body: some View {
            NavigationView {
                Button(action: {
                    self.isPresented.toggle()
                }) {
                    Text("Present")
                }
                .navigationBarTitle("Some title")
            }
            .present($isPresented, view: ModalView(isPresented: $isPresented))
        }
    }
    
    struct ModalView: View {
    
        @Binding var isPresented: Bool
    
        var body: some View {
            Button(action: {
                self.isPresented.toggle()
            }) {
                Text("Dismiss")
            }
        }
    }
    

    【讨论】:

    • 知道如何在从 ModalView 关闭后在 ContentView 上触发 onAppear 吗?
    • 嗯,这很难。不确定现在是否可行。您可以只修改.present 方法,使其具有一个可选的已关闭回调,该回调在每次关闭呈现的屏幕时都会被调用。
    • 我尝试过使用 .transition(.move) 它可以在视图之间触发诸如 onAppear 之类的事件,但它似乎也存在 NavigationView 可见性的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-11-06
    • 2011-05-22
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多