list - 如何在 SwiftUI 的列表中启用选择
问题描述
我正在尝试使用 SwiftUI 创建一个简单的多选列表。我无法使它工作。
List 接受第二个参数,它是一个 SelectionManager,所以我尝试创建一个的具体实现。但是,它永远不会被调用,并且行永远不会突出显示。
import SwiftUI
var demoData = ["Phil Swanson", "Karen Gibbons", "Grant Kilman", "Wanda Green"]
struct SelectKeeper : SelectionManager{
var selections = Set<UUID>()
mutating func select(_ value: UUID) {
selections.insert(value)
}
mutating func deselect(_ value: UUID) {
selections.remove(value)
}
func isSelected(_ value: UUID) -> Bool {
return selections.contains(value)
}
typealias SelectionValue = UUID
}
struct SelectionDemo : View {
@State var selectKeeper = SelectKeeper()
var body: some View {
NavigationView {
List(demoData.identified(by: \.self)){ name in
Text(name)
}
.navigationBarTitle(Text("Selection Demo"))
}
}
}
#if DEBUG
struct SelectionDemo_Previews : PreviewProvider {
static var previews: some View {
SelectionDemo()
}
}
#endif
代码运行良好,但行不突出显示,并且永远不会调用 SelectionManager 代码。
解决方案
根据您的需要,有两种方法可以做到这一点:
如果您想在“编辑模式”中执行此操作:
在选择重要之前,您必须在列表中启用“编辑模式”。从界面List
:
/// Creates an instance.
///
/// - Parameter selection: A selection manager that identifies the selected row(s).
///
/// - See Also: `View.selectionValue` which gives an identifier to the rows.
///
/// - Note: On iOS and tvOS, you must explicitly put the `List` into Edit
/// Mode for the selection to apply.
@available(watchOS, unavailable)
public init(selection: Binding<Selection>?, content: () -> Content)
你可以通过EditButton
在某处添加一个视图来做到这一点。之后,你只需要为实现的东西绑定一个 var SelectionManager
(你不需要在这里滚动你自己的:D)
var demoData = ["Phil Swanson", "Karen Gibbons", "Grant Kilman", "Wanda Green"]
struct SelectionDemo : View {
@State var selectKeeper = Set<String>()
var body: some View {
NavigationView {
List(demoData.identified(by: \.self), selection: $selectKeeper){ name in
Text(name)
}
.navigationBarItems(trailing: EditButton())
.navigationBarTitle(Text("Selection Demo \(selectKeeper.count)"))
}
}
}
如果您不想使用“编辑模式”:
在这一点上,我们将不得不推出自己的。注意:这个实现有一个错误,这意味着只有Text
才会导致选择发生。可以这样做,Button
但由于 Beta 2 中的更改删除borderlessButtonStyle()
了它看起来很傻,而且我还没有找到解决方法。
struct Person: Identifiable, Hashable {
let id = UUID()
let name: String
}
var demoData = [Person(name: "Phil Swanson"), Person(name: "Karen Gibbons"), Person(name: "Grant Kilman"), Person(name: "Wanda Green")]
struct SelectKeeper : SelectionManager{
var selections = Set<UUID>()
mutating func select(_ value: UUID) {
selections.insert(value)
}
mutating func deselect(_ value: UUID) {
selections.remove(value)
}
func isSelected(_ value: UUID) -> Bool {
return selections.contains(value)
}
typealias SelectionValue = UUID
}
struct SelectionDemo : View {
@State var selectKeeper = Set<UUID>()
var body: some View {
NavigationView {
List(demoData) { person in
SelectableRow(person: person, selectedItems: self.$selectKeeper)
}
.navigationBarTitle(Text("Selection Demo \(selectKeeper.count)"))
}
}
}
struct SelectableRow: View {
var person: Person
@Binding var selectedItems: Set<UUID>
var isSelected: Bool {
selectedItems.contains(person.id)
}
var body: some View {
GeometryReader { geo in
HStack {
Text(self.person.name).frame(width: geo.size.width, height: geo.size.height, alignment: .leading)
}.background(self.isSelected ? Color.gray : Color.clear)
.tapAction {
if self.isSelected {
self.selectedItems.remove(self.person.id)
} else {
self.selectedItems.insert(self.person.id)
}
}
}
}
}
推荐阅读
- java - 无法在模块“deployment.examplapp.war”中定义类 oracle.jdbc.OracleDriver
- regex - Find all words in a string that contain tags using regex
- php - Woocommerce set minimum order for a specific user role
- r - mlogit "提供的行名长度错误", R
- angular5 - Angular 5 模板
不会填充 --aot 开关,但不会填充它。没有错误 - java - HTTPClient 可以建立多少个并行连接
- swift - 处理是否应该在警报“之后”进行?
- oracle - 是否可以在没有动态 sql 的情况下将变量列名传递给 ORACLE 更新语句
- tensorflow - 使用连续变量和分类变量的 Tensorflow 嵌入
- c# - 如何将引导程序应用程序包含到 WIX msi 安装程序以检查 .NET 框架?