Xcode 8 / Swift 3: простой код UIPicker не работает

У меня есть протоколы:

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { 

У меня есть данные:

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

В viewDidLoad меня есть:

 muteForPicker.delegate = self muteForPicker.dataSource = self 

Тогда у меня есть необходимые методы:

 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) { } 

Я все еще получаю

Тип viewcontroller не соответствует протоколу UIPickerViewDataSource

UIPickerViewDataSource метода numberOfComponentsInPickerView изменен в Swift 3, так как это причина, по которой вы получаете эту ошибку.

 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) { } 

Для более подробной информации читайте документацию Apple по UIPickerView .

Примечание. Вы также должны добавить _ как первую метку параметра, как и другие методы в вашем методе UIPickerViewDelegate который является titleForRow и didSelectRow .

Детали

Xcode 9.2, Swift 4

Быстрый KIT для использования 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.. 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) } 

Полный образец

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)") } } 

результат

введите описание изображения здесь введите описание изображения здесь

Давайте будем гением компьютера.