iOS UIPickerView

时间:2020-02-23 14:45:56  来源:igfitidea点击:

在本教程中,我们将讨论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()。