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()。

