在不使用导航链接的情况下获取 SwiftUI 列表中的选定项目
Posted
技术标签:
【中文标题】在不使用导航链接的情况下获取 SwiftUI 列表中的选定项目【英文标题】:Get selected item in SwiftUI list without using a navigation link 【发布时间】:2021-08-09 18:49:15 【问题描述】:我正在编写一个类似于看板的 SwiftUI Mac 应用程序。该应用程序具有三个列表:Todo、Doing 和 Done。每个列表的底部是一个按钮,用于将任务移动到另一个列表。例如,待办事项列表有一个开始执行按钮。从待办事项列表中选择一项任务并单击该按钮应将任务从待办事项列表移动到正在执行的列表中。
我见过的每个 SwiftUI 列表选择示例都使用导航链接。选择一个列表项会将您带到另一个视图。但我不想在选择列表项时导航到另一个视图。我想要选定的任务,以便在单击按钮时更改其状态并将其移动到正确的列表中。
这是我的一份清单的代码。
struct TodoList: View
// The board has an array of tasks.
@Binding var board: KanbanBoard
@State private var selection: Task? = nil
@State private var showAddSheet = false
var body: some View
VStack
Text("Todo")
.font(.title)
List(todoTasks, selection: $selection) task in
Text(task.title)
HStack
Button(action: showAddSheet = true , label:
Label("Add", systemImage: "plus.square")
)
Spacer()
Button(action: selection?.status = .doing, label:
Label("Start Doing", systemImage: "play.circle")
)
.sheet(isPresented: $showAddSheet)
AddTaskView(board: $board)
var todoTasks: [Task]
// Task conforms to Identifiable.
// A task has a status that is an enum: todo, doing, or done.
return board.tasks.filter $0.status == .todo
当我点击一个列表项时,它没有被选中。
如何在不使用导航链接的情况下从列表中获取所选项目?
解决方法
Tamas Sengel 的回答让我找到了解决方法。为每个列表项提供一个开始执行按钮,这样我就不必跟踪选择。
List(todoTasks, id: \.self) task in
HStack
Text(task.title)
Button
task.status = .doing
label:
Text("Start Doing")
解决方法有助于我的具体情况。但我将保持这个问题的开放性,希望得到一个答案,为想要获取所选列表项的人提供更好的选择,而不是使用按钮。
【问题讨论】:
【参考方案1】:在列表和操作中使用按钮,将@State
变量设置为当前列表项。
@State var currentTask: Task?
List(todoTasks, id: \.self) task in
Button
currentTask = task
label:
Text(task.title)
【讨论】:
【参考方案2】:使用.environment(\.editMode, .constant(.active))
开启选择功能。
import SwiftUI
struct ContentView: View
struct Ocean: Identifiable, Hashable
let name: String
let id = UUID()
private var oceans = [
Ocean(name: "Pacific"),
Ocean(name: "Atlantic"),
Ocean(name: "Indian"),
Ocean(name: "Southern"),
Ocean(name: "Arctic")
]
@State private var multiSelection = Set<UUID>()
var body: some View
NavigationView
List(oceans, selection: $multiSelection)
Text($0.name)
.navigationTitle("Oceans")
.environment(\.editMode, .constant(.active))
.onTapGesture
// This is a walk-around: try how it works without `asyncAfter()`
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05, execute:
print(multiSelection)
)
Text("\(multiSelection.count) selections")
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【讨论】:
以上是关于在不使用导航链接的情况下获取 SwiftUI 列表中的选定项目的主要内容,如果未能解决你的问题,请参考以下文章
如何在不中断删除的情况下在 SwiftUI 中实现 TextField 列表
如何在不使用swiftUI附带的幻灯片删除的情况下创建自定义删除按钮我没有使用列表,只是使用foreach循环