![](/img/trans.png)
[英]SwiftUI: NavigationView/List with programmatic selection under macOS
[英]SwiftUI on macOS: list with detail view and multiple selection
TL;博士:
我無法在 macOS 上擁有包含詳細視圖和多項選擇的列表。
更詳細地說:
這是啟動時的“應用程序”,頂部有一個列表,下面有一個詳細表示。 因為我使用的是列表的初始化程序init(_:selection:rowContent:)
,所以selection
的類型是Binding<SelectionValue?>?
根據Apple的文檔,我可以免費使用鍵盤箭頭鍵選擇項目。
這是完整的代碼:
import SwiftUI
@main
struct UseCurorsInLisstApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(ViewModel())
}
}
}
class ViewModel: ObservableObject {
@Published var items = [Item(), Item(), Item(), Item(), Item()]
@Published var selectedItem: Item? = nil
}
struct Item: Identifiable, Hashable {
let id = UUID()
}
struct ContentView: View {
@EnvironmentObject var vm: ViewModel
var body: some View {
VStack {
List(vm.items, id: \.self, selection: $vm.selectedItem) { item in
VStack {
Text("Item \(item.id.uuidString)")
Divider()
}
}
Divider()
Group {
if let item = vm.selectedItem {
Text("Detail item \(item.id.uuidString)")
} else {
Text("No selection…")
}
}
.frame(minHeight: 200.0, maxHeight: .infinity)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
現在,到目前為止已經取得了成功,我認為能夠 select 不止一行會很有用,所以我仔細研究了List(_:selection:rowContent:)
,其中selection
的類型是Binding<Set<SelectionValue>>?
. 為了能夠獲得詳細視圖,我只是對
ViewModel
:
class ViewModel: ObservableObject {
@Published var items = [Item(), Item(), Item(), Item(), Item()]
@Published var selectedItem: Item? = nil
@Published var selectedItems: Set<Item>? = nil {
didSet {
if selectedItems?.count == 1, let item = selectedItems?.first {
selectedItem = item
}
}
}
}
和ContentView
:
struct ContentView: View {
@EnvironmentObject var vm: ViewModel
var body: some View {
VStack {
List(vm.items, id: \.self, selection: $vm.selectedItems) { item in
VStack {
Text("Item \(item.id.uuidString)")
Divider()
}
}
Divider()
Group {
if vm.selectedItems?.count == 1, let item = vm.selectedItems?.first {
Text("Detail item \(item.id.uuidString)")
} else {
Text("No or multiple selection…")
}
}
.frame(minHeight: 200.0, maxHeight: .infinity)
}
}
}
現在的問題是,我不能再通過單擊或箭頭鍵 select 行中的一個項目。 這是我遇到的限制還是我“持有錯誤”?
使用按鈕並將其插入集合中。 鍵盤選擇也適用於 shift +(向上/向下箭頭)
class ViewModel: ObservableObject {
@Published var items = [Item(), Item(), Item(), Item(), Item()]
@Published var selectedItem: Item? = nil
@Published var selectedItems: Set<Item> = []
}
struct ContentView: View {
@EnvironmentObject var vm: ViewModel
var body: some View {
VStack {
List(vm.items, id: \.self, selection: $vm.selectedItems) { item in
Button {
vm.selectedItem = item
vm.selectedItems.insert(item)
} label: {
VStack {
Text("Item \(item.id.uuidString)")
Divider()
}
}
.buttonStyle(PlainButtonStyle())
}
Divider()
Group {
if let item = vm.selectedItem {
Text("Detail item \(item.id.uuidString)")
} else {
Text("No or multiple selection…")
}
}
.frame(minHeight: 200.0, maxHeight: .infinity)
}
}
}
添加刪除:
Button {
vm.selectedItem = item
if vm.selectedItems.contains(item) {
vm.selectedItems.remove(item)
} else {
vm.selectedItems.insert(item)
}
}
編輯簡單地需要給一個空白的默認值來設置。 因為在 nil 中它永遠不會 append 設置需要初始化。
@Published var selectedItems: Set<Item> = [] {
實際上我的錯誤非常愚蠢——將selectedItems
-set 設置為可選會阻止列表正常工作。 向@Raja Kishan 致敬,他的提議將我推向了正確的方向。
這是完整的工作代碼:
import SwiftUI
@main
struct UseCurorsInLisstApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(ViewModel())
}
}
}
class ViewModel: ObservableObject {
@Published var items = [Item(), Item(), Item(), Item(), Item()]
@Published var selectedItems = Set<Item>()
}
struct Item: Identifiable, Hashable {
let id = UUID()
}
struct ContentView: View {
@EnvironmentObject var vm: ViewModel
var body: some View {
VStack {
List(vm.items, id: \.self, selection: $vm.selectedItems) { item in
VStack {
Text("Item \(item.id.uuidString)")
Divider()
}
}
Divider()
Group {
if vm.selectedItems.count == 1, let item = vm.selectedItems.first {
Text("Detail item \(item.id.uuidString)")
} else {
Text("No or multiple selection…")
}
}
.frame(minHeight: 200.0, maxHeight: .infinity)
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.