あなたは、むしろ思慮深く、データソースとデリゲートを実装し、これを達成するためにUIPickerViewをサブクラス化する必要はありません。あなたはこのクラスはコールバックvar selected: (([String: Any]) -> Void)?
を持って見たよう
import UIKit
class PickerViewSource: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
init(pickerView: UIPickerView) {
super.init()
pickerView.dataSource = self
pickerView.delegate = self
}
var selected: (([String: Any]) -> Void)?
let data = [
["title": "Group a", "selectable": false],
["title": "title a1", "selectable": true],
["title": "title a2", "selectable": true],
["title": "title a3", "selectable": true],
["title": "Group b", "selectable": false],
["title": "title b1", "selectable": true],
["title": "title b2", "selectable": true],
["title": "Group c", "selectable": false],
["title": "title c1", "selectable": true],
["title": "title c2", "selectable": true],
]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return data.count
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let d = data[row]
if let selectable = d["selectable"] as? Bool, selectable == true {
if let view = view as? ItemView, let title = d["title"] as? String{
view.label.text = title
return view
}
let view = ItemView()
if let title = d["title"] as? String{
view.label.text = title
}
return view
}
if let selectable = d["selectable"] as? Bool, selectable == false {
if let view = view as? GroupView, let title = d["title"] as? String{
view.label.text = title
return view
}
let view = GroupView()
if let title = d["title"] as? String{
view.label.text = title
}
return view
}
return UIView()
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
var index = row
if let selectable = data[row]["selectable"] as? Bool, selectable == false {
index += 1
pickerView.selectRow(index, inComponent: 0, animated: true)
}
selected?(data[index])
}
}
:
は、私はこのようなやったテストとして、あなたは両方を実装するクラスを持つことをお勧めします。選択可能なアイテムについてのみ呼び出されます。
のViewControllerは、ソースをインスタンス化し、コールバック設定:
class ViewController: UIViewController {
var pickerViewSource: PickerViewSource?
@IBOutlet weak var pickerView: UIPickerView! {
didSet{
pickerViewSource = PickerViewSource(pickerView: pickerView)
pickerViewSource?.selected = {
selected in
print(selected)
}
}
}
}
とcompletnessために、ビュー:
class BaseView: UIView {
var label: UILabel = UILabel()
override func layoutSubviews() {
super.layoutSubviews()
self.addSubview(label)
label.frame = self.bounds
}
}
class GroupView: BaseView {
override func layoutSubviews() {
super.layoutSubviews()
label.backgroundColor = .orange
}
}
class ItemView: BaseView {
}
の代わりに選択することによって、選択を強制します次の行、あなたはグループを選択することができますが、d選択コールバックを送信しません。しかし、選択可能なものが何も設定されていないことを確実にするには、選択解除コールバックを追加する必要があります。
var selectedElement: [String:Any]?
var deselected: (([String: Any]) -> Void)?
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if let element = selectedElement {
deselected?(element)
selectedElement = nil
}
if let selectable = data[row]["selectable"] as? Bool, selectable == true {
let element = data[row]
selected?(element)
selectedElement = element
}
}
今、あなたは、エンまたは無効にボタンをすなわちし、ユーザーインターフェイスを変更するコールバックselected
とdeselected
を使用することができます。完全例えば
は、私はちょうど発表され、このサンプルコードを参照してください。https://github.com/vikingosegundo/PickerWithSectionTitlesExample
あなたは – Starlord
あなたは少し手の込んだてもらえことを行うことができますか? Duncan Cが示唆したものとは別の方法がありますか?チュートリアルへのリンクはありますか? – Micheal
ホールドオン...いくつかの簡単なサンプルコードを作成 – Starlord