我试图了解是否有办法在
NavigationSplitView
视图不是 content
的情况下使用 List
。我想要一个没有 content
的自定义 List
视图。但问题是,如果我不使用 List
,iPhone 上就不会显示详细信息视图。
这是我的起点代码 - 运行良好,即详细视图在 iPhone 上滑入。
import SwiftUI
struct ContentView: View {
@State private var selectedCategory: Category?
@State private var selectedRecipe: Recipe?
var body: some View {
NavigationSplitView {
List(Category.allCases, selection: $selectedCategory) { category in
NavigationLink(value: category) {
Text(category.rawValue)
}
}
} content: {
if let selectedCategory {
List(Recipe.allCases, selection: $selectedRecipe) { recipe in
NavigationLink(value: recipe) {
Text(recipe.rawValue)
}
}
} else {
Text("Nothing selected")
}
} detail: {
if let selectedRecipe {
Text(selectedRecipe.rawValue)
} else {
Text("Nothing selected")
}
}
}
}
enum Category: String, CaseIterable, Identifiable {
var id: String {
self.rawValue
}
case main
case settings
}
enum Recipe: String, CaseIterable, Identifiable {
var id: String {
self.rawValue
}
case omelet
case cereal
}
现在,这是一个修改,允许我删除不需要的(就我而言)
NavigationLink
。这段代码也可以正常工作。该按钮(点击时)可以更新 selectedRecipe
,从而使详细信息视图滑入 iPhone 上。
...
List(Recipe.allCases, selection: $selectedRecipe) { recipe in
// NavigationLink(value: recipe) {
//
// Text(recipe.rawValue)
// }
Button {
self.selectedRecipe = recipe
} label: {
Text(recipe.rawValue)
}
}
...
但是由于我在自定义
List
视图中不需要 NavigationLink
或 content
,所以我尝试了这个(简化的代码)。这适用于 iPad,其中 detail
区域显示 selectedRecipe
,但在 iPhone 上,detail
视图不会滑入并取代 content
视图。
...
Button {
self.selectedRecipe = Recipe.omelet
} label: {
Text(Recipe.omelet.rawValue)
}
...
无论如何,我只是对正在发生的任何魔法感到困惑,需要
List
与 selection
绑定来设置 self.selectedRecipe
实际上会导致详细视图出现在 iPhone 上。
任何指导表示赞赏。
NavigationSplitView
不能被 List
以外的任何东西“驱动”。另请参阅 Apple 开发者论坛上的此讨论。
也就是说,我发现向侧边栏/内容列添加
navigationDestination
确实会导致导航到详细信息列。例如:
} content: {
if let selectedCategory {
Button {
self.selectedRecipe = Recipe.omelet
} label: {
Text(Recipe.omelet.rawValue)
}
.navigationDestination(item: $selectedRecipe) {
Text($0.rawValue)
}
} else {
Text("Nothing selected")
}
} detail: {
// the detail parameter here is only used for the case when nothing is selected
// the actual detail view goes in the navigationDestination above
Text("Nothing selected")
}
我不认为这是
navigationDestination
的预期用法,因为它的文档没有提到它可以在 NavigationSplitView
中使用。由于一些实现细节的原因,这种方法有效的事实可能只是巧合。
另一种解决方法是用
List
隐藏
opacity(0)
} content: {
if let selectedCategory {
ZStack {
List(Recipe.allCases, selection: $selectedRecipe) { _ in
Text("")
}
.opacity(0)
Button {
self.selectedRecipe = Recipe.omelet
} label: {
Text(Recipe.omelet.rawValue)
}
}
} else {
Text("Nothing selected")
}
}