Skip to content

Instantly share code, notes, and snippets.

@hanrw
Created March 17, 2025 04:09
Show Gist options
  • Save hanrw/b9328df416a81d7c1c48cf648018c50f to your computer and use it in GitHub Desktop.
Save hanrw/b9328df416a81d7c1c48cf648018c50f to your computer and use it in GitHub Desktop.
GenericPickerView
// Copyright © 2025 onegai.com. All rights reserved.
import SwiftUI
struct GenericPickerView<T: CaseIterable & RawRepresentable>: View where T.RawValue == String, T: Hashable {
@Binding var selection: T
private let labelImageName: String
private let localizedString: (T) -> String
init(
selection: Binding<T>,
labelImageName: String = "chevron.up.chevron.down",
localizedString: @escaping (T) -> String
) {
self._selection = selection
self.labelImageName = labelImageName
self.localizedString = localizedString
}
var body: some View {
Menu {
ForEach(Array(T.allCases), id: \.self) { value in
Button {
selection = value
} label: {
labelContent(for: value)
}
}
} label: {
menuLabel(for: localizedString(selection), labelImageName: labelImageName)
}
}
private func labelContent(for value: T) -> some View {
HStack {
Text(localizedString(value))
.font(.caption2)
if value == selection {
Image(systemName: "checkmark")
.font(.callout)
}
}
}
}
func menuLabel(for text: String, labelImageName: String) -> some View {
HStack(spacing: 2) {
Text(text)
.font(.footnote)
Image(systemName: labelImageName)
.font(.footnote)
}
.padding(4)
.padding(.horizontal, 2)
.background {
RoundedRectangle(cornerRadius: 6).fill(.white.opacity(0.8))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment