В зависимости от того, что вы хотите, есть два способа сделать это:
Если вы хотите сделать это в «режиме редактирования»:
Вы должны включить «Режим редактирования» в списке, прежде чем выбор будет иметь значение. Из интерфейса для 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
к вашему виду где-то. После этого вам просто нужно связать переменную для чего-то, что реализует 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)
}
}
}
}
}