iOS UIPickerView
在本教程中,我们将讨论iOS应用程序中的UIPickerView组件。
UIPickerView
UIPickerView是一个UI元素,用于从垂直轮中显示的多个选项中进行选择。
它与Android或者Web UI中的下拉菜单非常相似。
车轮在UIPickerView中被称为组件。
一个UIPickerView可以托管一个或者多个组件。
每个组件都可以包含独立的数据,并且可以选择和更改。
通常,数组用于在UIPickerView组件的行中显示数据。
要在UIPickerView中显示数据,您必须在应用程序中采用协议UIPickerViewDataSource并实现其必需的方法。
您必须采用协议UIPickerViewDelegate才能显示行并允许用户进行选择。
如果您在ViewController中不使用后一种协议,则可能会得到如下所示的结果:
以下是四个最重要的功能:
func numberOfComponents(in pickerView: UIPickerView) -> Int func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
titleForRow用于在UIPickerView组件中显示数据。
,只要任何UIPickerView行的选择didSelectRow
被调用。
在下一节中介绍复杂的内容之前,让我们在XCode Single View Application Project中实现一个简单的UIPicker。
项目情节提要
我们添加了一个UIPickerView,一个UILabel和一个UITextField。
我们将在UILabel中的UIPickerView中显示选择。
稍后,我们将在底部创建另一个UIPickerView来选择UITextField的文本。
代码
下面给出了ViewController.swift的代码:
import UIKit class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { @IBOutlet weak var myTextField: UITextField! @IBOutlet weak var myLabel: UILabel! @IBOutlet weak var topPickerView: UIPickerView! var arrayOf100 = Array(0...100) var arrayOf2 = Array(1...2) var labelString = "" override func viewDidLoad() { super.viewDidLoad() topPickerView.delegate = self topPickerView.delegate?.pickerView?(topPickerView, didSelectRow: 0, inComponent: 0) topPickerView.delegate?.pickerView?(topPickerView, didSelectRow: 0, inComponent: 1) } func numberOfComponents(in pickerView: UIPickerView) -> Int { return 2 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { if component == 0{ return arrayOf2.count } else{ return arrayOf100.count } } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { if component == 0 { return String(arrayOf2[row]) } else{ return String(arrayOf100[row]) } } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { let digitsValue = arrayOf2[topPickerView.selectedRow(inComponent: 0)] let decimalValue = arrayOf100[topPickerView.selectedRow(inComponent: 1)] myLabel.text = "Value is \(digitsValue).\(decimalValue)" if component == 0 { print(String(arrayOf2[row])) } else{ print(String(arrayOf100[row])) } } }
" topPickerView.delegate = self"是最重要的一行。
它以某种方式在UIPickerView实例上激活协议。
我们将返回2个组件,并为每个组件填充一个不同的数组。
只要任何行选择didSelectRow
被调用。
但是,它不会调用选择中的所有组件。
为此,我们使用selectedRow(inComponent :)从组件的选定行中获取值。
然后将它们附加并显示在字符串中。
由于初始状态不会触发didSelectRow
,因此我们在viewDidLoad
方法的两个组件上调用该方法。
在iOS模拟器上运行上述应用程序时的输出为:
现在,让我们创建另一个UIPickerView,它将代替键盘打开。
UIPickerView代替键盘
要添加UIPickerView代替键盘,我们只需要将UITextField上的inputView属性设置为UIPickerView。
func createAnotherPicker() { let anotherPicker = UIPickerView() anotherPicker.delegate = self anotherPicker.delegate?.pickerView?(anotherPicker, didSelectRow: 0, inComponent: 0) myTextField.inputView = anotherPicker }
以下是ViewController.swift的更新代码。
我们在委托方法中需要做的就是检查UIPickerView实例的类型,以便同时使用两个UIPickerViews。
import UIKit class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { @IBOutlet weak var myTextField: UITextField! @IBOutlet weak var myLabel: UILabel! @IBOutlet weak var topPickerView: UIPickerView! var arrayOf100 = Array(0...100) var arrayOf2 = Array(1...2) var labelString = "" let anotherPicker = UIPickerView() var arrayOfCountries = ["San Franceco","USA","Germany","China", "France","Japan", "Australia", "Greece"] override func viewDidLoad() { super.viewDidLoad() topPickerView.delegate = self topPickerView.delegate?.pickerView?(topPickerView, didSelectRow: 0, inComponent: 0) topPickerView.delegate?.pickerView?(topPickerView, didSelectRow: 0, inComponent: 1) createAnotherPicker() } func createAnotherPicker() { anotherPicker.delegate = self anotherPicker.delegate?.pickerView?(anotherPicker, didSelectRow: 0, inComponent: 0) myTextField.inputView = anotherPicker } func numberOfComponents(in pickerView: UIPickerView) -> Int { if pickerView == topPickerView{ return 2 } else{ return 1 } } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { if pickerView == topPickerView{ if component == 0{ return arrayOf2.count } else{ return arrayOf100.count } } else{ return arrayOfCountries.count } } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { if pickerView == topPickerView{ if component == 0 { return String(arrayOf2[row]) } else{ return String(arrayOf100[row]) } } else{ return arrayOfCountries[row] } } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if pickerView == topPickerView{ let digitsValue = arrayOf2[topPickerView.selectedRow(inComponent: 0)] let decimalValue = arrayOf100[topPickerView.selectedRow(inComponent: 1)] myLabel.text = "Value is \(digitsValue).\(decimalValue)" if component == 0 { print(String(arrayOf2[row])) } else{ print(String(arrayOf100[row])) } } else{ myTextField.text = arrayOfCountries[row] } } }
上面更新的实际应用程序的输出为:
为了消除UIPickerView,我们可以使用view.endEditing(true)设置touchesBegan方法。
更好的选择是在UIPickerView上添加带有关闭按钮的UIToolbar。
UIPickerView和UIToolbar
在ViewController.swift文件中添加以下函数
func createToolbar() { let toolbar = UIToolbar() toolbar.sizeToFit() let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.closePickerView)) toolbar.setItems([doneButton], animated: false) toolbar.isUserInteractionEnabled = true myTextField.inputAccessoryView = toolbar }
我们在UIToolBar中添加了一个Button,并将Toolbar设置为inputAccessoryView。
这意味着单击UITextField时,它将显示在UIPickerView上方。
单击"完成"按钮时,将执行以下方法:
@objc func closePickerView() { view.endEditing(true) }
这将关闭输入视图。
不要忘记在viewDidLoad方法中添加方法createToolbar()。