如何在 SwiftUI 的列表中启用选择

2024-01-05

我正在尝试使用 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到你的某个地方的视图。之后,您只需为实现的东西绑定一个 varSelectionManager(你不需要在这里自己动手: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)"))
        }
    }
}

This approach looks like this: enter image description here

如果您不想使用“编辑模式”:

在这一点上,我们将不得不推出我们自己的。 注意:此实现有一个错误,这意味着只有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)
                }
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 SwiftUI 的列表中启用选择 的相关文章

随机推荐