Skip to content

Instantly share code, notes, and snippets.

@sbeitzel
Created April 7, 2021 23:04
Show Gist options
  • Save sbeitzel/a203a6343d6fec7076234149e775f6fb to your computer and use it in GitHub Desktop.
Save sbeitzel/a203a6343d6fec7076234149e775f6fb to your computer and use it in GitHub Desktop.
SwiftUI multiple selection list
import SwiftUI
/// UI View which presents a list of items, any number of which may
/// be selected. Each item must conform to `Identifiable` and
/// to `Hashable`.
struct MultiSelectItemList<T: Identifiable & Hashable>: View {
private let items: [T]
private let modified: (Set<T>) -> Void
private let itemString: (T) -> String
@State private var selected: Set<T>
/// Initialize a MultiSelectItemList
///
/// - Parameters:
/// - items: the items to be displayed
/// - selected: the currently selected items
/// - modified: callback, called when the selection changes
/// - itemString: method to get a displayable string label for a given item
init(items: [T], selected: Set<T>, modified: @escaping (Set<T>) -> Void, itemString: @escaping (T) -> String) {
self.items = items
self.modified = modified
self.itemString = itemString
_selected = State(wrappedValue: selected)
}
var body: some View {
ScrollView {
ForEach(items) { item in
MultiSelectItemRow(
item: item,
selected: selected.contains(item),
action: {
if selected.contains(item) {
selected.remove(item)
} else {
selected.insert(item)
}
modified(selected)
},
itemString: itemString
)
}
}
}
}
import SwiftUI
struct MultiSelectItemRow<T>: View {
let item: T
let selected: Bool
let action: () -> Void
let itemString: (T) -> String
var body: some View {
HStack {
icon
Text(itemString(item))
Spacer()
}
.background(background)
.onTapGesture {
action()
}
}
var background: Color {
if selected {
return .accentColor
} else {
return .clear
}
}
var icon: some View {
ZStack {
if selected {
Image(systemName: "checkmark.circle")
}
EmptyView()
}
.frame(width: 30, height: 20, alignment: .center)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment