想象一下一个典型的应用程序,它有登录、登录/注册和某种类型的内容。当应用程序加载时,您需要决定显示哪个视图。一个简单的实现可能如下所示:
struct ContentView: View {
//assuming some centralized state that keeps track of basic user activity
@State var applicationState = getApplicationState()
var body: some View {
if !applicationState.hasSeenOnboarding {
return OnBoarding()
}
if !applicationState.isSignedIn {
return Registration()
}
return MainContent()
}
}显然,这种方法失败了,因为SwiftUI视图需要一个不透明的some View返回类型。这可以使用AnyView包装器类型来缓解(尽管很麻烦),它提供了类型擦除,并允许编译下面的代码。
struct ContentView: View {
//assuming some centralized state that keeps track of basic user activity
@State var applicationState = getApplicationState()
var body: some View {
if !applicationState.hasSeenOnboarding {
return AnyView(OnBoarding())
}
if !applicationState.isSignedIn {
return AnyView(Registration())
}
return AnyView(MainContent())
}
}有没有一种不需要使用AnyView的更正确的方法?SceneDelegate中是否有功能可以处理到完全不同的视图层次结构的转换?
发布于 2019-09-04 19:02:28
可能做这些事情的最好的SwiftUI-y方法是使用Group视图:
import SwiftUI
struct ContentView: View {
@State private var applicationState = getApplicationState()
var body: some View {
Group {
if !applicationState.hasSeenOnboarding {
OnBoarding()
} else if !applicationState.isSignedIn {
Registration()
} else {
MainContent()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}需要注意的最重要的一点是,通过这种方式,您将不会依赖于AnyView的类型擦除(如果不是严格需要的话,可以避免这种情况)。
如果您想将初始视图创建封装在一个方法中,请不要使用类型擦除。请改用some关键字:
import SwiftUI
struct ContentView: View {
@State private var applicationState = getApplicationState()
private func initialView() -> some View {
if !applicationState.hasSeenOnboarding {
OnBoarding()
} else if !applicationState.isSignedIn {
Registration()
} else {
MainContent()
}
}
var body: some View {
initialView()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}https://stackoverflow.com/questions/57780005
复制相似问题