如何解决macOS 上的 SwiftUI:具有详细视图和多项选择的列表
TL;DR:
我无法在 macOS 上创建包含详细信息视图和多项选择的列表。
更详细:
这是启动时的“应用程序”,顶部是列表,下面是详细表示。因为我正在使用列表的初始化程序 init(_:selection:rowContent:)
,其中 selection
根据 Apple 的文档属于 Binding<SelectionValue?>?
类型,所以我可以免费使用键盘箭头键选择项目。
完整代码如下:
import SwiftUI
@main
struct UseCurorsInLisstApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(viewmodel())
}
}
}
class viewmodel: ObservableObject {
@Published var items = [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()
}
}
现在,到目前为止已经取得了成功,我认为能够选择多于一行会很有用,所以我仔细研究了 List(_:selection:rowContent:)
,其中 selection
的类型为 { {1}}。为了能够有详细的视图,我只是对
Binding<Set<SelectionValue>>?
:
viewmodel
和class viewmodel: ObservableObject {
@Published var items = [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
现在的问题是我无法再选择行中的项目,无论是通过单击还是通过箭头键。这是我遇到的限制还是我“认为错误”?
解决方法
使用按钮并将其插入集合中。键盘选择也适用于 shift +(向上/向下箭头)
class ViewModel: ObservableObject {
@Published var items = [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 中它永远不会追加到 set 需要初始化。
@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()]
@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,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)
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。