你可以摆脱Only root-level navigation destinations are effective for a navigation stack with a homogeneous path
通过将路径类型更改为NavigationPath
.
@State private var path: NavigationPath = .init()
但随后您会收到一条消息/错误,我认为它更好地解释了问题A navigationDestination for “Swift.String” was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used.
Apple 认为扫描所有可用视图的效率非常低,因此他们将使用navigationDestination
将优先。
试想一下,如果你的OnBoardingView
还可以选择"RegisterView"
.navigationDestination(for: String.self) { string in
switch string{
case "UserTypeView":
UserTypeView(path: $path)
case "RegisterView":
Text("fakie register view")
default:
Text("No view has been set for \(string)")
}
}
SwiftUI 如何选择合适的呢?
那么如何“修复”呢?您可以尝试这个替代方案。
import SwiftUI
@available(iOS 16.0, *)
struct CealUIApp: View {
@State private var path: NavigationPath = .init()
var body: some View {
NavigationStack(path: $path){
OnBoardingView(path: $path)
.navigationDestination(for: ViewOptions.self) { option in
option.view($path)
}
}
}
//Create an `enum` so you can define your options
enum ViewOptions{
case userTypeView
case register
//Assign each case with a `View`
@ViewBuilder func view(_ path: Binding<NavigationPath>) -> some View{
switch self{
case .userTypeView:
UserTypeView(path: path)
case .register:
RegisterView()
}
}
}
}
@available(iOS 16.0, *)
struct OnBoardingView: View {
@Binding var path: NavigationPath
var body: some View {
Button {
//Append to the path the enum value
path.append(CealUIApp.ViewOptions.userTypeView)
} label: {
Text("Hello")
}
}
}
@available(iOS 16.0, *)
struct UserTypeView: View {
@Binding var path: NavigationPath
var body: some View {
Button {
//Append to the path the enum value
path.append(CealUIApp.ViewOptions.register)
} label: {
Text("Hello")
}
}
}
@available(iOS 16.0, *)
struct RegisterView: View {
var body: some View {
Text("Register")
}
}
@available(iOS 16.0, *)
struct CealUIApp_Previews: PreviewProvider {
static var previews: some View {
CealUIApp()
}
}