Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an UIPickerView with a Done button?

I am having difficulties to make an UIPickerView with a done button to appear when the users taps a UITextField. This is my code so far. Everything builds fine, but when I tap the text field, the keyboard appears, not the picker.

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {   @IBOutlet var textField1: UITextField!  let pickerData = ["11", "12", "13"]      @IBAction func textButton(sender: AnyObject) {      let picker: UIPickerView     picker = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300))     picker.backgroundColor = .whiteColor()      picker.showsSelectionIndicator = true     picker.delegate = self     picker.dataSource = self      let toolBar = UIToolbar()     toolBar.barStyle = UIBarStyle.Default     toolBar.translucent = true     toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)     toolBar.sizeToFit()      let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")     let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)     let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")      toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)     toolBar.userInteractionEnabled = true      textField1.inputView = picker     textField1.inputAccessoryView = toolBar     }    override func viewDidLoad() {     super.viewDidLoad()     // Do any additional setup after loading the view, typically from a nib. }  override func didReceiveMemoryWarning() {     super.didReceiveMemoryWarning()     // Dispose of any resources that can be recreated. }  func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {     return 1 }  func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {     return pickerData.count }  func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {     return pickerData[row] }  func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {     textField1.text = pickerData[row] }  func donePicker() {      textField1.resignFirstResponder()  }     } 
like image 401
Alberto O. Avatar asked Jul 30 '15 15:07

Alberto O.


2 Answers

Add this code to your viewDidLoad() instead of method

let picker: UIPickerView picker = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 300)) picker.backgroundColor = .whiteColor()  picker.showsSelectionIndicator = true picker.delegate = self picker.dataSource = self  let toolBar = UIToolbar() toolBar.barStyle = UIBarStyle.default toolBar.isTranslucent = true toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1) toolBar.sizeToFit()  let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: self, action: #selector(self. donePicker)) let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil) let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItem.Style.plain, target: self, action: #selector(self. donePicker))  toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false) toolBar.userInteractionEnabled = true  textField1.inputView = picker textField1.inputAccessoryView = toolBar 
like image 100
iAnurag Avatar answered Sep 28 '22 22:09

iAnurag


I think it's better to make a custom class to remove code from controller.

Swift 4/5 example:

import Foundation import UIKit  protocol ToolbarPickerViewDelegate: class {     func didTapDone()     func didTapCancel() }  class ToolbarPickerView: UIPickerView {      public private(set) var toolbar: UIToolbar?     public weak var toolbarDelegate: ToolbarPickerViewDelegate?      override init(frame: CGRect) {         super.init(frame: frame)         self.commonInit()     }      required init?(coder aDecoder: NSCoder) {         super.init(coder: aDecoder)         self.commonInit()     }      private func commonInit() {         let toolBar = UIToolbar()         toolBar.barStyle = UIBarStyle.default         toolBar.isTranslucent = true         toolBar.tintColor = .black         toolBar.sizeToFit()          let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped))         let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)         let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelTapped))          toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)         toolBar.isUserInteractionEnabled = true          self.toolbar = toolBar     }      @objc func doneTapped() {         self.toolbarDelegate?.didTapDone()     }      @objc func cancelTapped() {         self.toolbarDelegate?.didTapCancel()     } } 

Usage example:

class MyViewController: UIViewController {      @IBOutlet weak var textField: UITextField!     fileprivate let pickerView = ToolbarPickerView()     fileprivate let titles = ["0", "1", "2", "3"]      override func viewDidLoad() {         super.viewDidLoad()          self.textField.inputView = self.pickerView         self.textField.inputAccessoryView = self.pickerView.toolbar          self.pickerView.dataSource = self         self.pickerView.delegate = self         self.pickerView.toolbarDelegate = self          self.pickerView.reloadAllComponents()     } }  extension MyViewController: UIPickerViewDataSource, UIPickerViewDelegate {      func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {         return self.titles.count     }      func numberOfComponents(in pickerView: UIPickerView) -> Int {         return 1     }      func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {         return self.titles[row]     }      func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {         self.textField.text = self.titles[row]     } }  extension MyViewController: ToolbarPickerViewDelegate {      func didTapDone() {         let row = self.pickerView.selectedRow(inComponent: 0)         self.pickerView.selectRow(row, inComponent: 0, animated: false)         self.textView.text = self.titles[row]         self.textField.resignFirstResponder()     }      func didTapCancel() {         self.textField.text = nil         self.textField.resignFirstResponder()     } } 
like image 37
Eridana Avatar answered Sep 28 '22 22:09

Eridana