In this tutorial, we’ll be customising the UIPickerView properties in our iOS Application. In the previous tutorial, we implemented the UIPickerView class and discussed some of the important helper properties and functions.
UIPickerView
We know that UIPickerView requires the two protocols: UIPickerViewDataSource
, UIPickerViewDelegate
.
Besides the required methods that we had discussed, we can use the following methods to customize the UI of the UIPickerView.
1 2 3 4 5 |
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 |
Using the above three methods we can override the width and height of the cell, and the view of each cell.
Inside the viewForRow
method, we can customize the UILabel by creating our own or just create any random custom view such as a UIImage + UILabel.
To change the background color of the UIPickerView simply use the backgroundColor property over the instance.
In the following section, we’ll first create a UIPickerView with a custom label. Later we’ll add a custom view in place of the custom label.
Project Storyboard
We’ve added two UITextField and connected them in the ViewController.swift file.
Code
The code for the ViewController.swift file is given below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
import UIKit class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { @IBOutlet weak var textField1: UITextField! @IBOutlet weak var textField2: UITextField! let picker1 = UIPickerView() var arrayOfCountries = ["India","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 } } |
In the viewForRow
method, we have set the UILabel color and a system font.
We must update the text here.
UIToolbar Tint color is set on the Buttons present in the Toolbar.
The output when the above application was run on a simulator is:
In the next section, we’ll create a Dynamic UIPickerView on the second UITextField. We will show a UIImage from the assets in the custom rows.
UIPickerView Row with UIImage
The code for the updated ViewController.swift file is given below;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import UIKit class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate { @IBOutlet weak var textField1: UITextField! @IBOutlet weak var textField2: UITextField! let picker1 = UIPickerView() var arrayOfCountries = ["India","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 } } } |
In the above code, we’ve also added TextFieldDelegate Procol in order to detect which UITextField is focused. Based on that we display the relevant UIPickerView with the respective data.
In the textFieldDidBeginEditing method, we set the activeField Property to 1 or 2 based on the UITextField that is focused.
After that we update the UIPickerView by calling reloadAllComponents()
The output of the above application in action is given below
This brings an end to this tutorial. You can download the project from the link below: