可以制作通用枚举 UIPickerView
Possible to Make a Generic Enum UIPickerView
是否可以编写一个通用的 UIPickerView 子类,您可以在其中传入任意枚举类型,并让它用上述枚举的所有情况填充选择器视图?
注意:对于任意传入的枚举类型,通常需要执行此操作。
试试这个:
enum SomeValues: Int {
static var count: Int { return SomeValues.lastValue.hashValue + 1 }
case valueA = 0
case valueB = 1
case valueC = 2
case lastValue = 3
case noValue = 4
func rawString() -> String {
return String(describing: self)
}
}
使用选择器的值:
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return SomeValues.count
}
// MARK: - UIPickerViewDelegate
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
guard let value = SomeValues(rawValue: component), value != .noValue else { return "Handle however you want" }
return value.rawString()
}
所以我终于能够编写一个通用的枚举感知选择器视图。这就是我所做的。首先我做了一个 PickableEnum 协议,如下:
protocol PickableEnum: Hashable {
static var allValues: [Self] {get}
var pickerText: String {get}
}
我需要能够大致了解所有枚举案例是什么。这是我在网上找到的 allValues 属性 的工作。
https://theswiftdev.com/2017/01/05/18-swift-gist-generic-allvalues-for-enums/)
代码如下:
extension PickableEnum {
static func cases() -> AnySequence<Self> {
typealias S = Self
return AnySequence { () -> AnyIterator<S> in
var raw = 0
return AnyIterator {
let current : Self = withUnsafePointer(to: &raw) { [=11=].withMemoryRebound(to: S.self, capacity: 1) { [=11=].pointee } }
guard current.hashValue == raw else { return nil }
raw += 1
return current
}
}
}
static var allValues: [Self] {
return Array(self.cases())
}
}
PickableEnum 还有一个名为 pickerText 的只读字符串 属性,用于获取将出现在选取器界面中的文本。
其余的都是微不足道的。让您的 UI class 采用适当类型的通用限定符,然后相应地配置您的 UIPickerView:
class EnumPickerView<T:PickableEnum> : UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
private let enumCases = T.allValues
private var currentValue: T
init(frame: CGRect, initialValue: T) {
currentValue = initialValue
super.init(frame: frame)
dataSource = self
delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var value: T {
get {
return currentValue
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return enumCases.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return enumCases[row].pickerText
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
currentValue = enumCases[row]
}
}
是否可以编写一个通用的 UIPickerView 子类,您可以在其中传入任意枚举类型,并让它用上述枚举的所有情况填充选择器视图?
注意:对于任意传入的枚举类型,通常需要执行此操作。
试试这个:
enum SomeValues: Int {
static var count: Int { return SomeValues.lastValue.hashValue + 1 }
case valueA = 0
case valueB = 1
case valueC = 2
case lastValue = 3
case noValue = 4
func rawString() -> String {
return String(describing: self)
}
}
使用选择器的值:
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return SomeValues.count
}
// MARK: - UIPickerViewDelegate
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
guard let value = SomeValues(rawValue: component), value != .noValue else { return "Handle however you want" }
return value.rawString()
}
所以我终于能够编写一个通用的枚举感知选择器视图。这就是我所做的。首先我做了一个 PickableEnum 协议,如下:
protocol PickableEnum: Hashable {
static var allValues: [Self] {get}
var pickerText: String {get}
}
我需要能够大致了解所有枚举案例是什么。这是我在网上找到的 allValues 属性 的工作。
https://theswiftdev.com/2017/01/05/18-swift-gist-generic-allvalues-for-enums/)
代码如下:
extension PickableEnum {
static func cases() -> AnySequence<Self> {
typealias S = Self
return AnySequence { () -> AnyIterator<S> in
var raw = 0
return AnyIterator {
let current : Self = withUnsafePointer(to: &raw) { [=11=].withMemoryRebound(to: S.self, capacity: 1) { [=11=].pointee } }
guard current.hashValue == raw else { return nil }
raw += 1
return current
}
}
}
static var allValues: [Self] {
return Array(self.cases())
}
}
PickableEnum 还有一个名为 pickerText 的只读字符串 属性,用于获取将出现在选取器界面中的文本。
其余的都是微不足道的。让您的 UI class 采用适当类型的通用限定符,然后相应地配置您的 UIPickerView:
class EnumPickerView<T:PickableEnum> : UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
private let enumCases = T.allValues
private var currentValue: T
init(frame: CGRect, initialValue: T) {
currentValue = initialValue
super.init(frame: frame)
dataSource = self
delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var value: T {
get {
return currentValue
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return enumCases.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return enumCases[row].pickerText
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
currentValue = enumCases[row]
}
}