这就是为什么 MRE 很重要,这就是为什么我在第一条评论中提到它,你介绍了NavigationSplitView
.
场景1
如果您正在使用NavigationSplitView
你必须注射EnvironmentObject
to the NavigationSplitView
.
NavigationSplitView{
/*other stuff that includes a navigationDestination*/
}.environmentObject(navModel)
场景2
当只与NavigationStack
你必须注射NavigationStack
NavigationStack{
/*other stuff that includes a navigationDestination*/
}.environmentObject(navModel)
场景3 - 已弃用
当只与NavigationView
你必须注射NavigationView
NavigationView{
/*other stuff that includes a NavigationLink*/
}.environmentObject(navModel)
您的样品
只需将注入代码向下移动一行即可。
import Combine
import SwiftUI
@available(iOS 16.0, *)
struct SplitTestView: View {
@State var selectedCategory: Category?
var categories = Category.allCases
@StateObject var coordinator = Coordinator3() //<-- Switch to StateObject
@StateObject var test = Test()
var body: some View {
NavigationSplitView {
List(categories, selection: $selectedCategory) { category in
NavigationLink(category.localizedName, value: category)
}
} detail: {
NavigationStack(path: $coordinator.path) {
switch selectedCategory {
case .dessert:
Text(selectedCategory!.localizedName)
case .pancake:
VStack {
Text("Navigation stack")
.padding()
NavigationLink("NavigationLink to enter first page", value: Destination.firstPage)
.padding()
NavigationLink("NavigationLink to enter second page", value: Destination.secondPage)
.padding()
}
.navigationDestination(for: Destination.self) { destination in
if destination == .firstPage {
FirstPage()
} else {
Text(
"SecondPage()"
)
}
}
case .salad: Text(selectedCategory!.localizedName)
case .sandwich: Text(selectedCategory!.localizedName)
case .none: Text("hi")
}
}
}.environmentObject(test) //<<--- Add to the NavigationSplitView - The NavigationLink's are presenting in a separate column than the Stack, the only thing they share is the split view.
}
}
enum Destination {
case firstPage
case secondPage
}
enum Category: Int, Hashable, CaseIterable, Identifiable, Codable {
case dessert
case pancake
case salad
case sandwich
var id: Int { rawValue }
var localizedName: LocalizedStringKey {
switch self {
case .dessert:
return "Dessert"
case .pancake:
return "Pancake"
case .salad:
return "Salad"
case .sandwich:
return "Sandwich"
}
}
}
@available(iOS 16.0, *)
class Coordinator3: ObservableObject {
@Published var path = NavigationPath()
func gotoHomePage() {
path.removeLast(path.count)
}
func tapOnEnter() {
path.append(Destination.firstPage)
}
func tapOnFirstPage() {
path.append(Destination.secondPage)
}
func tapOnSecondPage() {
path.removeLast()
}
func test() {
path.removeLast(path.count)
path.append(2)
}
}
class Test :ObservableObject {
var name = "test"
}
@available(iOS 16.0, *)
struct SplitTestView_Previews: PreviewProvider {
static var previews: some View {
SplitTestView()
}
}
struct FirstPage: View {
@EnvironmentObject var test: Test
var body: some View {
Text("First Page \(test.name)")
}
}
地址信息
在迁移指南中,苹果讨论了这两种类型之间的差异。
https://developer.apple.com/documentation/swiftui/migration-to-new-navigation-types https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types
他们称其内部为NavigationStack
“内容”
NavigationStack {
/* content */
}
以及里面的NavigationSplitView
“列”
NavigationSplitView {
/* column 1 */
} content: {
/* column 2 */
} detail: {
/* column 3 */
}
在各自的设置中,“栏目”和“内容”仅共享NavigationSplitView
or NavigationStack
分别与NavigationLink
s/navigationDestination
.
A NavigationLink
inside NavigationStack
那是在里面NavigationSplitView
在其自己的专栏中呈现。
注入应该始终发生在最上面的共享处View
.