自定义iOS UIPickerView

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

在本教程中,我们将在iOS应用程序中自定义UIPickerView属性。
在上一教程中,我们实现了UIPickerView类,并讨论了一些重要的帮助程序属性和功能。

UIPickerView

我们知道UIPickerView需要两个协议:" UIPickerViewDataSource"," UIPickerViewDelegate"。

除了我们已经讨论过的必需方法之外,我们还可以使用以下方法来自定义UIPickerView的UI。

func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView

使用以上三种方法,我们可以覆盖单元格的宽度和高度以及每个单元格的视图。

在viewForRow方法中,我们可以通过创建自己的UILabel来定制UILabel,或者只创建任意随机的自定义视图,例如UIImage + UILabel。

要更改UIPickerView的背景颜色,只需在实例上使用backgroundColor属性。

在以下部分中,我们将首先创建带有自定义标签的UIPickerView。
稍后,我们将添加一个自定义视图来代替自定义标签。

项目情节提要

我们添加了两个UITextField并将它们连接到ViewController.swift文件中。

代码

下面给出了ViewController.swift文件的代码:

import UIKit

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
  
  
  @IBOutlet weak var textField1: UITextField!
  @IBOutlet weak var textField2: UITextField!
  let picker1 = UIPickerView()
  var arrayOfCountries = ["San Franceco","USA","Germany","China", "France","Japan", "Australia", "Greece"]
  
  
  override func viewDidLoad() {
      super.viewDidLoad()
      //Do any additional setup after loading the view, typically from a nib.
      
      createPickerView()
      createToolbar()
  }
  
  func createPickerView()
  {
      picker1.delegate = self
      picker1.delegate?.pickerView?(picker1, didSelectRow: 0, inComponent: 0)
      textField1.inputView = picker1
      textField2.inputView = picker1
      picker1.backgroundColor = UIColor.brown
      
  }

  
  func createToolbar()
  {
      let toolbar = UIToolbar()
      toolbar.sizeToFit()
      toolbar.tintColor = UIColor.red
      toolbar.backgroundColor = UIColor.blue
      let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.closePickerView))
      toolbar.setItems([doneButton], animated: false)
      toolbar.isUserInteractionEnabled = true
      textField1.inputAccessoryView = toolbar
      textField2.inputAccessoryView = toolbar
  }
  
  @objc func closePickerView()
  {
      view.endEditing(true)
  }

  
  func numberOfComponents(in pickerView: UIPickerView) -> Int {
      return 1
  }
  
  func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
      
      return arrayOfCountries.count
  }
  
  func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
  {
      return arrayOfCountries[row]
  }
  
  func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
      
      textField1.text =  arrayOfCountries[row]
  }
  
  func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
      return 100.0
  }
  
  func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
      return 60.0
  }

  func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {

      var label:UILabel
      
      if let v = view as? UILabel{
          label = v
      }
      else{
          label = UILabel()
      }
      
      label.textColor = UIColor.yellow
      label.textAlignment = .left
      label.font = UIFont(name: "Helvetica", size: 16)
      
      label.text = arrayOfCountries[row]
      
      return label
  }
}

在viewForRow方法中,我们设置了UILabel颜色和系统字体。
我们必须在这里更新文本。

UIToolbar淡色在工具列上的按钮上设置。

在模拟器上运行上述应用程序时的输出为:

在下一部分中,我们将在第二个UITextField上创建一个动态UIPickerView。
我们将在自定义行中显示资产中的UIImage。

UIPickerView行与UIImage

更新的ViewController.swift文件的代码如下:

import UIKit

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate {
  
  
  @IBOutlet weak var textField1: UITextField!
  @IBOutlet weak var textField2: UITextField!
  let picker1 = UIPickerView()
  var arrayOfCountries = ["San Franceco","USA","Germany","China", "France","Japan", "Australia", "Greece"]
  var arrayOfColors = ["Red","Orange","Yellow","Green", "Blue","Black"]
  var activeTextField = 0
  
  
  override func viewDidLoad() {
      super.viewDidLoad()
      //Do any additional setup after loading the view, typically from a nib.
      
      textField1.delegate = self
      textField2.delegate = self
      createPickerView()
      createToolbar()
  }
  
  func createPickerView()
  {
      picker1.delegate = self
      picker1.delegate?.pickerView?(picker1, didSelectRow: 0, inComponent: 0)
      textField1.inputView = picker1
      textField2.inputView = picker1
      picker1.backgroundColor = UIColor.brown
  }

  
  func createToolbar()
  {
      let toolbar = UIToolbar()
      toolbar.sizeToFit()
      toolbar.tintColor = UIColor.red
      toolbar.backgroundColor = UIColor.blue
      let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(ViewController.closePickerView))
      toolbar.setItems([doneButton], animated: false)
      toolbar.isUserInteractionEnabled = true
      textField1.inputAccessoryView = toolbar
      textField2.inputAccessoryView = toolbar
  }
  
  @objc func closePickerView()
  {
      view.endEditing(true)
  }

  
  func numberOfComponents(in pickerView: UIPickerView) -> Int {
      return 1
  }
  
  func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
      
      switch activeTextField
      {
      case 1:
          return arrayOfCountries.count
      case 2:
          return arrayOfColors.count
      default:
          return arrayOfColors.count
      
      }
  }
  
  func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
  {
      switch activeTextField{
      case 1:
          return arrayOfCountries[row]
      case 2:
          return arrayOfColors[row]
      default:
          return arrayOfColors[row]
      }

  }
  
  func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
      switch activeTextField{
      
      case 1:
          textField1.text =  arrayOfCountries[row]
          break
          
      case 2:
          textField2.text = arrayOfColors[row]
          break

      default:
          textField1.text =  arrayOfCountries[row]
          break
          
      }
  }
  
  func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
      return 100.0
  }
  
  func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
      return 60.0
  }

  func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
      
      
      switch activeTextField{
      case 1:
      var label:UILabel
      
      if let v = view as? UILabel{
          label = v
      }
      else{
          label = UILabel()
      }
      
      label.textColor = UIColor.yellow
      label.textAlignment = .left
      label.font = UIFont(name: "Helvetica", size: 16)
      
      label.text = arrayOfCountries[row]
      
      return label
       
      case 2:
          
          let parentView = UIView()
          let label = UILabel(frame: CGRect(x: 60, y: 0, width: 80, height: 50))
          let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height:50))
          imageView.image = UIImage(named: "ic_launcher")
          label.text = arrayOfColors[row]
          parentView.addSubview(label)
          parentView.addSubview(imageView)
          
          return parentView
          
      default:
          return UILabel()
          
      }
  }
  
  func textFieldDidBeginEditing(_ textField: UITextField) {
      
      switch textField {
      case textField1:
          activeTextField = 1
          picker1.reloadAllComponents()
      case textField2:
          activeTextField = 2
          picker1.reloadAllComponents()
      default:
          activeTextField = 0
      }
      
  }
}

在上面的代码中,我们还添加了TextFieldDelegate Procol,以检测聚焦于哪个UITextField。
基于此,我们将显示相关的UIPickerView及其相应的数据。

在textFieldDidBeginEditing方法中,我们根据所关注的UITextField将activeField属性设置为1或者2。

之后,我们通过调用reloadAllComponents()更新UIPickerView。