example swift uipickerview swift3 xcode8 uipickerviewdatasource

uipickerview swift 4 example



Xcode 8/Swift 3: el código UIPicker simple no funciona (2)

Detalles

Xcode 9.2, Swift 4

KIT rápido para usar UIPickerView

PickerView

import UIKit class TextPicker: NSObject { var delegate: TextPickerDelegate? { didSet { textView.inputAccessoryView = delegate?.pickerView(inputAccessoryViewFor: self) } } fileprivate let pickerView = UIPickerView() fileprivate var textView = UITextField() fileprivate weak var parentViewController: UIViewController? public fileprivate(set) var items: [[String]] = [] init (parentViewController: UIViewController) { self.parentViewController = parentViewController super.init() setupPickerView() } deinit { textView.removeFromSuperview() } } // MARK: - Getter and Setter extension TextPicker { func set(items: [[String]]) { self.items = items pickerView.reloadAllComponents() } var selectedItems: [String] { var result = [String]() for index in 0..<pickerView.numberOfComponents { let selectedRow = pickerView.selectedRow(inComponent: index) if index < items.count && selectedRow < items[index].count { result.append(items[index][selectedRow]) } } return result } } // MARK: - setup Views extension TextPicker { fileprivate func setupPickerView() { pickerView.dataSource = self pickerView.delegate = self textView.inputView = pickerView parentViewController?.view.addSubview(textView) } func startPicking() { textView.becomeFirstResponder() } func endPicking() { textView.resignFirstResponder() } } // MARK: - UIPickerViewDataSource extension TextPicker: UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return items.count } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return items[component].count } } // MARK: - UIPickerViewDelegate extension TextPicker: UIPickerViewDelegate { func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return items[component][row] } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { delegate?.pickerView(didSelect: items[component][row], inRow: row, inComponent: component, delegatedFrom: self) } }

PickerViewDelegate

import UIKit protocol TextPickerDelegate { func pickerView(inputAccessoryViewFor pickerView: TextPicker) -> UIView? func pickerView(didSelect value: String, inRow row: Int, inComponent component: Int, delegatedFrom pickerView: TextPicker) }

Muestra completa

ViewController

import UIKit class ViewController: UIViewController { fileprivate var picker: TextPicker? weak var label: UILabel? override func viewDidLoad() { super.viewDidLoad() let stackView = UIStackView() stackView.axis = .vertical stackView.spacing = 16 view.addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true let label = UILabel() label.text = "..." label.textAlignment = .center self.label = label stackView.addArrangedSubview(label) let button = UIButton() button.setTitle("Button", for: .normal) button.setTitleColor(.blue, for: .normal) button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) stackView.addArrangedSubview(button) picker = TextPicker(parentViewController: self) picker?.delegate = self picker?.set(items: [["aaa", "bbb", "ccc"], ["1", "2", "3"]]) } @objc func buttonTapped() { picker?.startPicking() } } // MARK: PickerViewDelegate extension ViewController: TextPickerDelegate { @objc func pickerCancelAction() { picker?.endPicking() } @objc func pickerSetAction() { if let selectedItems = picker?.selectedItems { label?.text = "/(selectedItems)" } } func pickerView(inputAccessoryViewFor pickerView: TextPicker) -> UIView? { let view = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 30)) view.backgroundColor = .white let buttonWidth: CGFloat = 100 let cancelButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.width - buttonWidth - 10, y: 0, width: buttonWidth, height: 30)) cancelButton.setTitle("Cancel", for: .normal) cancelButton.setTitleColor(.black, for: .normal) cancelButton.setTitleColor(.lightGray, for: .highlighted) cancelButton.addTarget(self, action: #selector(pickerCancelAction), for: .touchUpInside) view.addSubview(cancelButton) let setButton = UIButton(frame: CGRect(x: 10, y: 0, width: buttonWidth, height: 30)) setButton.setTitle("Set", for: .normal) setButton.setTitleColor(.black, for: .normal) setButton.setTitleColor(.lightGray, for: .highlighted) setButton.addTarget(self, action: #selector(pickerSetAction), for: .touchUpInside) view.addSubview(setButton) return view } func pickerView(didSelect value: String, inRow row: Int, inComponent component: Int, delegatedFrom pickerView: TextPicker) { print("/(value)") } }

Resultado

Tengo protocolos:

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

Tengo datos:

let muteForPickerData = ["minute(s)","hour(s)"]

En viewDidLoad tengo:

muteForPicker.delegate = self muteForPicker.dataSource = self

Entonces he requerido métodos:

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return muteForPickerData.count } func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return muteForPickerData[row] } func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { }

Todavía consigo

El tipo viewcontroller no se ajusta al protocolo UIPickerViewDataSource


UIPickerViewDataSource método UIPickerViewDataSource numberOfComponentsInPickerView se cambia en Swift 3 de esta manera, esa es la razón por la que obtiene este error.

func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return muteForPickerData.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return muteForPickerData[row] } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { }

Para obtener más detalles, lea la documentación de Apple en UIPickerView .

Nota: También debe agregar _ como primera etiqueta de parámetro igual que otros métodos en su método UIPickerViewDelegate que es didSelectRow y didSelectRow .