Two UIPickerViews in one ViewController - swift

Two PickerViews selectTypeOfWorkChoices & selectLocationChoices do not appear correctly.
A function dismissPickerView() seems working well. However, another function "createPickerView()" has some problems. Although UIpickerviews appear, I cannot see the choices in UIPickerViews and I don't know why.
Could anyone help me figure out what's wrong with my code, please??
#IBOutlet weak var selectTypeOfWorkChoices: UIPickerView!
#IBOutlet weak var selectLocationChoices: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
createPickerView()
dismissPickerView()
}
var typeOfWork = ["--", "a", "b", "c"]
var location = ["--", "A", "B", "C"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
var countrows : Int = typeOfWork.count
if pickerView == selectLocationChoices {
countrows = self.location.count
}
return countrows
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == selectTypeOfWorkChoices {
let titleRow = typeOfWork[row]
return titleRow
}
else if pickerView == selectLocationChoices {
let titleRow = location[row]
return titleRow
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == selectTypeOfWorkChoices {
selectedPriority = typeOfWork[row]
selectTypeOfWork.text = selectedPriority
self.selectTypeOfWork.text = self.typeOfWork[row]
}
else if pickerView == selectLocationChoices {
locationSelectedPriority = location[row]
selectLocation.text = locationSelectedPriority
self.selectLocation.text = self.location[row]
}
}
var selectedPriority : String?
var locationSelectedPriority : String?
func createPickerView() {
let pickerView = UIPickerView()
pickerView.delegate = self
self.selectTypeOfWorkChoices.delegate = self
self.selectTypeOfWorkChoices.dataSource = self
self.selectLocationChoices.delegate = self
self.selectLocationChoices.dataSource = self
selectTypeOfWork.inputView = selectTypeOfWorkChoices
selectLocation.inputView = selectLocationChoices
}
#objc func dismissPickerView() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title:"Done", style: .plain, target: self, action: #selector(self.dismissKeyboard))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
selectTypeOfWork.inputAccessoryView = toolBar
selectLocation.inputAccessoryView = toolBar
}
#objc func dismissKeyboard () {
view.endEditing(true)
}

Reload the picker view after assigning an input view to your text field.
func createPickerView() {
let pickerView = UIPickerView()
pickerView.delegate = self
self.selectTypeOfWorkChoices.delegate = self
self.selectTypeOfWorkChoices.dataSource = self
self.selectLocationChoices.delegate = self
self.selectLocationChoices.dataSource = self
selectTypeOfWork.inputView = selectTypeOfWorkChoices
selectLocation.inputView = selectLocationChoices
//Reload Pickerview
self.selectTypeOfWorkChoices.reloadAllComponents()
self.selectLocationChoices.reloadAllComponents()
}

Related

How to use one pickerview for multiple textfield?

I am trying to build something (I am new to Xcode and swift) where I can choose a meal for a day from an array with Picker View, and I want my choice to display in that specific day's textfield. I have got this working, but for 1 day only. How can I get this same function working for all (7) days?
I managed to get the picker view when click on next textfield as well (Tuesday), but as I choose from the list the Mondays textfield will follow what I am doing for Tuesday. They are mirrored. I do get that I should probably make something to get thatTuesday-Picker unique somehow, but that's where Im stuck. I don't know what to change/write. Anyone with any ideas? I have googled around and find a lot regarding picker views but nothing for how they can been used in this specific way...
//
// ViewController.swift
// dropdown
//
// Created by -- on 2019-08-26.
// Copyright © 2019 --. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
// the menu
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
let tuesdayMenu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
//When a menu from the list is selected, it will be shown as a string
var mondaySelectedMenu: String?
var tuesdaySelectedMenu: String?
override func viewDidLoad() {
super.viewDidLoad()
//Call on these functions when loaded
createMondayMenuPicker()
createTuesdayMenuPicker()
createToolbar()
}
// This is the pickerView
func createMondayMenuPicker() {
let mondayMenuPicker = UIPickerView()
mondayMenuPicker.delegate = self
monday.inputView = mondayMenuPicker
}
func createTuesdayMenuPicker() {
let tuesdayMenuPicker = UIPickerView()
tuesdayMenuPicker.delegate = self
tuesday.inputView = tuesdayMenuPicker
}
// This is the "DONE" button
func createToolbar() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "DONE", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
monday.inputAccessoryView = toolBar
tuesday.inputAccessoryView = toolBar
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
// This is the details for the pickerView
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return Menu.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
mondaySelectedMenu = Menu[row]
tuesdaySelectedMenu = tuesdayMenu[row]
monday.text = mondaySelectedMenu
tuesday.text = tuesdaySelectedMenu
}
}
So, I want to call on that same array when click on all seven days but I want to display the unique choices for everyday chosen from that list. Any ideas? Thanks a lot!
One way to achieve this is to do using the below approach. I have separated out toolbar functionality into its own class.
Create a new class pickerview's toolbar (in this case i have called ToolbarPickerView.swift)
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()
}
}
In ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
var daysArray = [UITextField]()
let pickerView = ToolbarPickerView()
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
var selectedMenu : String?
override func viewDidLoad() {
super.viewDidLoad()
setupDelegateForPickerView()
setupDelegatesForTextFields()
}
func setupDelegatesForTextFields() {
//appending textfields in an array
daysArray += [monday, tuesday, wednesday, thursday, friday, saturday, sunday]
//using the array to set up the delegates, inputview for pickerview and also the inputAccessoryView for the toolbar
for day in daysArray {
day.delegate = self
day.inputView = pickerView
day.inputAccessoryView = pickerView.toolbar
}
}
func setupDelegateForPickerView() {
pickerView.dataSource = self
pickerView.delegate = self
pickerView.toolbarDelegate = self
}
}
Create an extension for textfield delegate
extension ViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.pickerView.reloadAllComponents()
}
}
Extension for pickerview and toolbar
extension ViewController : UIPickerViewDelegate, UIPickerViewDataSource {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.Menu.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// Check if the textfield isFirstResponder.
if monday.isFirstResponder {
monday.text = self.Menu[row]
} else if tuesday.isFirstResponder {
tuesday.text = self.Menu[row]
} else if wednesday.isFirstResponder {
wednesday.text = self.Menu[row]
} else if thursday.isFirstResponder {
thursday.text = self.Menu[row]
} else if friday.isFirstResponder {
friday.text = self.Menu[row]
} else if saturday.isFirstResponder {
saturday.text = self.Menu[row]
} else if sunday.isFirstResponder {
sunday.text = self.Menu[row]
} else {
//log errors
}
}
}
extension ViewController: ToolbarPickerViewDelegate {
func didTapDone() {
// let row = self.pickerView.selectedRow(inComponent: 0)
// self.pickerView.selectRow(row, inComponent: 0, animated: false)
// selectedMenu = self.Menu[row]
self.view.endEditing(true)
}
func didTapCancel() {
self.view.endEditing(true)
}
}
PickerView's didSelectRow function can be simplified by changing it to below
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
for day in daysArray {
if day.isFirstResponder {
day.text = self.Menu[row]
}
}
}
Hopefully this answer will help you.
Create a common picker class like below:
class PKMultiPicker: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
internal typealias PickerDone = (_ firstValue: String, _ secondValue: String) -> Void
private var doneBlock : PickerDone!
private var firstValueArray : [String]?
private var secondValueArray = [String]()
static var noOfComponent = 2
class func openMultiPickerIn(_ textField: UITextField? , firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, titles: [String]?, toolBarTint: UIColor = UIColor.black, doneBlock: #escaping PickerDone) {
let picker = PKMultiPicker()
picker.doneBlock = doneBlock
picker.openPickerInTextField(textField, firstComponentArray: firstComponentArray, secondComponentArray: secondComponentArray, firstComponent: firstComponent, secondComponent: secondComponent, toolBarTint: toolBarTint)
if titles != nil {
let label = UILabel(frame: CGRect(x: UIScreen.main.bounds.size.width/4 - 10, y: 0, width: 100, height: 30))
label.text = titles![0].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
if PKMultiPicker.noOfComponent > 1 {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
label.text = titles![1].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
} else {
label.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 30)
label.textAlignment = NSTextAlignment.center
}
}
}
private func openPickerInTextField(_ textField: UITextField?, firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, toolBarTint: UIColor = UIColor.black) {
firstValueArray = firstComponentArray
secondValueArray = secondComponentArray
self.delegate = self
self.dataSource = self
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(pickerCancelButtonTapped))
cancelButton.tintColor = toolBarTint
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(pickerDoneButtonTapped))
doneButton.tintColor = toolBarTint
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action:nil)
let toolbar = UIToolbar()
toolbar.sizeToFit()
let array = [cancelButton, spaceButton, doneButton]
toolbar.setItems(array, animated: true)
toolbar.backgroundColor = UIColor.lightText
textField?.inputView = self
textField?.inputAccessoryView = toolbar
let index = self.firstValueArray?.index(where: {$0.lowercased() == (firstComponent ?? "").lowercased() })
self.selectRow(index ?? 0, inComponent: 0, animated: true)
if PKMultiPicker.noOfComponent > 1 {
let index1 = self.secondValueArray.index(where: {$0.lowercased() == (secondComponent ?? "").lowercased() })
self.selectRow(index1 ?? 0, inComponent: 1, animated: true)
}
}
#IBAction private func pickerCancelButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
}
#IBAction private func pickerDoneButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
let index1 : Int?
let firstValue : String?
index1 = self.selectedRow(inComponent: 0)
if firstValueArray?.count == 0{return}
else{firstValue = firstValueArray?[index1!]}
var index2 :Int!
var secondValue: String!
if PKMultiPicker.noOfComponent > 1 {
index2 = self.selectedRow(inComponent: 1)
secondValue = secondValueArray[index2]
}
self.doneBlock((firstValue ?? ""), (secondValue ?? ""))
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return firstValueArray!.count
}
return secondValueArray.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return PKMultiPicker.noOfComponent
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0:
return firstValueArray?[row]
case 1:
return secondValueArray[row]
default:
return ""
}
}
}
Example Code to open picker and manage selection, there are some more options, you can manage number of components also:-
PKMultiPicker.noOfComponent = 1
PKMultiPicker.openMultiPickerIn(textField, firstComponentArray: ["Apple", "Mango","Grapes","Pine apple"], secondComponentArray: [], firstComponent: textField.text, secondComponent: nil, titles: nil, toolBarTint: AppColors.themeGreen) { (firstSelect, secondSelect) in
print("first select : \(firstSelect)")
textField.text = firstSelect // you can set text here to the respective text field.
}
Here #pawan_kumar has described a way for using same picker view for multiple textfields with same data. but you can bind different data sources for that as well. https://stackoverflow.com/a/60631018/10505343 has a sample code for that. here I use UITextField.isFirstResponder to decide what data should be loaded to the picker view. Hope this answer also will be helpful for you.

How to change UIPickerViewData when I select the different UITextField?

I want to show a UIPickerView when tapping a UITextField.
And I made a 'place' UITextField with a UIPickerView.
But, I don't know how to make another UITextField with a UIPickerView.
I tried to use 'switch', but UITextField was not a value, so I couldn't do it with 'switch'.
I want to change UIPickerViewData when I select the different UITextField.
How can I do?
Here's the codes.
Thank you!
#IBOutlet weak var place: UITextField!
#IBOutlet weak var product: UITextField!
#IBOutlet weak var number: UITextField!
let placeArray = ["A", "B", "C", "D", "E", "F"]
let productArray = ["Apple", "Banana", "Grape"]
let numberArray = ["1", "2", "3", "4", "5", "6"]
var pickerView = UIPickerView()
var textField: UITextField!
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return placeArray.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
place.text = placeArray[row]
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return placeArray[row]
}
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(displayPickerView))
tapGesture.numberOfTapsRequired = 1
place.addGestureRecognizer(tapGesture)
}
#objc private func displayPickerView() {
if textField == nil {
self.textField = UITextField(frame: .zero)
textField.inputView = self.pickerView
self.view.addSubview(textField)
}
textField.becomeFirstResponder()
}
Very simple way to do this.
var placePickerView = UIPickerView()
var productPickerView = UIPickerView()
var numberPickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
placePickerView.delegate = self
placePickerView.dataSource = self
place.inputView = placePickerView
productPickerView.delegate = self
productPickerView.dataSource = self
product.inputView = productPickerView
numberPickerView.delegate = self
numberPickerView.dataSource = self
number.inputView = numberPickerView
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
var numberOfRows: Int = 1
if pickerView == placePickerView {
numberOfRows = placeArray.count
} else if pickerView == productPickerView {
numberOfRows = productArray.count
} else if pickerView == numberPickerView {
numberOfRows = numberArray.count
}
return numberOfRows
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == placePickerView {
place.text = placeArray[row]
} else if pickerView == productPickerView {
productType.text = productArray[row]
} else if pickerView == numberPickerView {
transactionType.text = numberArray[row]
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
var title: String?
if pickerView == placePickerView {
title = placeArray[row]
} else if pickerView == productPickerView {
title = productArray[row]
} else if pickerView == numberPickerView {
title = numberArray[row]
}
return title
}

Select first or any row with done button in UIPickerView and UIDatePicker for Swift

I have a ViewController with 4 UITextFields. First 3 are populated by their own UIPickerViews and the 4th is populated by a UIDatePicker.
I want a done button to be able to select the first row of each picker or select whichever row is selected if not the first.
Below is the code that works for the first UIPicker. Got it from Selecting first row in UIPickerView issue.
func doneButton(sender: AnyObject) {
let row = pickerView1.selectedRow(inComponent: 0);
pickerView(pickerView1, didSelectRow: row, inComponent:0)
view.endEditing(true)
}
How do I enable the done button to work independently for all 4 pickers?
Here is the full code.
Any help much appreciated.
var selectedItemsArray = [String]()
class RunInputViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate{
var pickerView1 = UIPickerView()
var pickerView2 = UIPickerView()
var pickerView3 = UIPickerView()
var pickerView4 = UIDatePicker()
#IBOutlet weak var runTypeTextField: UITextField!
#IBOutlet var runTextField: UITextField!
#IBOutlet var snowTypeTextField: UITextField!
#IBOutlet var dateTextField: UITextField!
#IBAction func saveRun(_ sender: Any){
if (runTypeTextField.text != ""){
runFeedList.append(runTypeTextField.text!)
runTypeTextField.text = ""
}
}
override func viewDidLoad() {
super.viewDidLoad()
createToolbar()
pickerView1 = UIPickerView()
pickerView2 = UIPickerView()
pickerView3 = UIPickerView()
pickerView4 = UIDatePicker()
pickerView1.delegate = self
pickerView1.dataSource = self
pickerView2.delegate = self
pickerView2.dataSource = self
pickerView3.delegate = self
pickerView3.dataSource = self
pickerView1.tag = 0
pickerView2.tag = 1
pickerView3.tag = 2
pickerView4.tag = 3
self.runTypeTextField.inputView = self.pickerView1;
self.runTextField.inputView = self.pickerView2;
self.snowTypeTextField.inputView = self.pickerView3;
self.dateTextField.inputView = self.pickerView4;
pickerView4.addTarget(self, action: #selector(datePickerValueChanged(sender:)), for: .valueChanged)
pickerView4.datePickerMode = UIDatePickerMode.time
//let currentDate = NSDate()
//pickerView4.minimumDate = currentDate as Date
//pickerView4.date = currentDate as Date
pickerView4.timeZone = NSTimeZone.local
pickerView4.minuteInterval = 5
}
func createToolbar() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
//Customizations
toolBar.barTintColor = .black
toolBar.tintColor = .white
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(RunInputViewController.doneButton(sender:)))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
runTypeTextField.inputAccessoryView = toolBar
runTextField.inputAccessoryView = toolBar
snowTypeTextField.inputAccessoryView = toolBar
dateTextField.inputAccessoryView = toolBar
}
func doneButton(sender: AnyObject) {
let row = pickerView1.selectedRow(inComponent: 0);
pickerView(pickerView1, didSelectRow: row, inComponent:0)
view.endEditing(true)
}
func dismissKeyboard() {
view.endEditing(true)
}
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
pickerView4.datePickerMode = UIDatePickerMode.time
dateTextField.text = dateFormatter.string(from: sender.date)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 0 {
return runType.count
} else if pickerView.tag == 1 {
return selectedItemsArray.count
} else if pickerView.tag == 2 {
return snowType.count
}
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView.tag == 0 {
return runType[row]
} else if pickerView.tag == 1 {
return selectedItemsArray[row]
} else if pickerView.tag == 2 {
return snowType[row]
}
return ""
}
var selectedRow: Int = 0
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedRow = row
if pickerView == pickerView1 {
runTypeTextField.text = runType[row]
switch row {
case 0:
selectedItemsArray = RunGreen
case 1:
selectedItemsArray = RunBlue
case 2:
selectedItemsArray = RunBlack
case 3:
selectedItemsArray = RunDoubleBlack
default:
selectedItemsArray = []
}
pickerView2.reloadAllComponents()
} else if pickerView == pickerView2 {
let item = selectedItemsArray[row]
if selectedItemsArray == rRunGreen {
runTextField.text = item
} else if selectedItemsArray == RunBlue {
runTextField.text = item
} else if selectedItemsArray == rRunBlack {
runTextField.text = item
} else if selectedItemsArray == RunDoubleBlack {
runTextField.text = item
}
}
if pickerView.tag == 2 {
snowTypeTextField.text = snowType[row]
}
}
}
check this code working with two picker with different array inputs and one Date picker
import UIKit
class PickerViewController: UIViewController,UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var pickerVieww: UIPickerView!
#IBOutlet weak var DateePicker: UIDatePicker!
#IBOutlet weak var newPickr: UIPickerView!
var viewControllerArray = [String]()
var viewControllerArray1 = [String]()
var value = Int()
var value1 = Int()
override func viewDidLoad() {
super.viewDidLoad()
pickerVieww.delegate = self
pickerVieww.dataSource = self
newPickr.delegate = self
newPickr.dataSource = self
pickerVieww.tag = 1
newPickr.tag = 2
viewControllerArray = ["controller1","controller2","controller3"]
viewControllerArray1 = ["controller4","controller5","controller6","controller7"]
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == pickerVieww
{
return viewControllerArray.count
}
else if pickerView == newPickr
{
return viewControllerArray1.count
}
return 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pickerVieww
{
return viewControllerArray[row]
}
else if pickerView == newPickr
{
return viewControllerArray1[row]
}
return ""
}
func pickerView(_ pickerView: UIPickerView,didSelectRow row: Int,inComponent component: Int)
{
}
#IBAction func DoneButton(_ sender: Any) {
let row = pickerVieww.selectedRow(inComponent: 0);
print("pickervieww value: \(row)")
let row1 = newPickr.selectedRow(inComponent: 0);
print("newpicker value: \(row1)")
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy"
let date:String = dateFormatter.string(from: DateePicker.date)
print("date: \(date)")
}
}
Console output on a button Action
So I figured out the answer to my own question. I had tried to create separate code for each UITextFiled and UIPickerView as suggested by #user3589771 but I was missing something.
My original code had
runTypeTextField.inputAccessoryView = toolBar
runTextField.inputAccessoryView = toolBar
snowTypeTextField.inputAccessoryView = toolBar
dateTextField.inputAccessoryView = toolBar
but once I separated the .inputAccessoryView for each UITextField is all came together.
I finally sorted it out and the answer is below.
func createToolbar() {
// Tool bar for 1st UIPickerView
let toolBar1 = UIToolbar()
toolBar1.sizeToFit()
toolBar1.barTintColor = .black
toolBar1.tintColor = .white
let doneButton1 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(RunInputViewController.doneButton1(sender:)))
toolBar1.setItems([doneButton1], animated: false)
toolBar1.isUserInteractionEnabled = true
runTypeTextField.inputAccessoryView = toolBar1
// Tool bar for 2nd UIPickerView
let toolBar2 = UIToolbar()
toolBar2.sizeToFit()
toolBar2.barTintColor = .black
toolBar2.tintColor = .white
let doneButton2 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(RunInputViewController.doneButton2(sender:)))
toolBar2.setItems([doneButton2], animated: false)
toolBar2.isUserInteractionEnabled = true
runTextField.inputAccessoryView = toolBar2
// Tool bar for 3rd UIPickerView
let toolBar3 = UIToolbar()
toolBar3.sizeToFit()
toolBar3.barTintColor = .black
toolBar3.tintColor = .white
let doneButton3 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(RunInputViewController.doneButton3(sender:)))
toolBar3.setItems([doneButton3], animated: false)
toolBar3.isUserInteractionEnabled = true
snowTypeTextField.inputAccessoryView = toolBar3
// Tool bar for UIDatePicker
let toolBar4 = UIToolbar()
toolBar4.sizeToFit()
toolBar4.barTintColor = .black
toolBar4.tintColor = .white
let doneButton4 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(RunInputViewController.doneButton4))
toolBar4.setItems([doneButton4], animated: false)
toolBar4.isUserInteractionEnabled = true
dateTextField.inputAccessoryView = toolBar4
}
// Done button for 1st UIPickerView
func doneButton1(sender: AnyObject) {
let row1 = pickerView1.selectedRow(inComponent: 0);
pickerView(pickerView1, didSelectRow: row1, inComponent:0)
view.endEditing(true)
}
// Done button for 2nd UIPickerView
func doneButton2(sender: AnyObject) {
let row2 = pickerView2.selectedRow(inComponent: 0);
pickerView(pickerView2, didSelectRow: row2, inComponent:0)
view.endEditing(true)
}
// Done button for 3rd UIPickerView
func doneButton3(sender: AnyObject) {
let row3 = pickerView3.selectedRow(inComponent: 0);
pickerView(pickerView3, didSelectRow: row3, inComponent:0)
view.endEditing(true)
}
// Done button for UIDatePicker
func doneButton4(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy HH:mm"
dateTextField.text = formatter.string(from: pickerView4.date)
self.view.endEditing(true)
}

Multiple Pickerviews

I want to build a viewcontroller which contains three pickerviews (which has three same options). I am having problems on how to show one specific row to the label. My code:
I changed other parts still getting errors. Edited variables' first letters to lowercase.
#IBOutlet weak var picker1: UIPickerView!
#IBOutlet weak var picker2: UIPickerView!
#IBOutlet weak var picker3: UIPickerView!
var Array = ["Shake","Swipe Up","Swipe Right"]
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label3: UILabel!
var placementAnswer = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
picker1.delegate = self
picker1.dataSource = self
picker1.tag = 1
picker2.delegate = self
picker2.dataSource = self
picker2.tag = 2
picker3.delegate = self
picker3.dataSource = self
picker3.tag = 3
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Array[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return Array.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
#IBAction func save3(_ sender: AnyObject) {
}
#IBAction func save2(_ sender: AnyObject) {
}
#IBAction func save1(_ sender: AnyObject) {
if (placementAnswer == 0){
label1.text = "Shake"
}
else if(placementAnswer == 1){
label1.text = "Swipe Up"
}
else{
label1.text = "Swipe Right"
}
if (placementAnswer == 0){
label2.text = "Shake"
}
else if(placementAnswer == 1){
label2.text = "Swipe Up"
}
else{
label2.text = "Swipe Right"
}
if (placementAnswer == 0){
label3.text = "Shake"
}
else if(placementAnswer == 1){
label3.text = "Swipe Up"
}
else{
label3.text = "Swipe Right"
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
picker1.delegate = self
picker1.dataSource = self
picker1.tag = 1
picker2.delegate = self
picker2.dataSource = self
picker1.tag = 2
picker3.delegate = self
picker3.dataSource = self
picker1.tag = 3
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView.tag == 1 {
// do things for pickerview 1
label1.text = row
}
else if pickerView.tag == 2 {
// do things for pickerview 2
label2.text = row
}else {
// do for pickerview 3
}
placementAnswer = row
}
}
Differentiate by using tag
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
picker1.delegate = self
picker1.dataSource = self
picker1.tag = 1
picker2.delegate = self
picker2.dataSource = self
picker1.tag = 2
picker3.delegate = self
picker3.dataSource = self
picker1.tag = 3
}
so in your delegate methods just check the tag
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Array[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView.tag == 1 {
// do things for pickerview 1
Label1.text = Array[row]
}
else if pickerView.tag == 2 {
// do things for pickerview 2
Label2.text = Array[row]
}else {
// do for pickerview 3
}
}
Here you are # h44f33z. How I can make each section dependent with each other? for example, if i choose "shake" for behavior name 1, it wont be available for behavior name 2 and 3. Each behavior name section will have one corresponding action. thanks!

How to set data for multiple UIpickerviews in Swift?

I have uiviewcontroller with uitextfields, when users tap on the textfields uipickerview appears as shown in the attachment.
How can I make multiple uipickerview? For example, when the user tap on the countries textfields a pickerview shows up with countries array data and when users tap on the gender textfields uipickerview shows the genders array data and so on. I tried but only able to do it for one array which is countries as shown in my code. would appreciate if you could show me how to do it for the rest of my uitextfields.
import UIKit
class testVC: UIViewController,UITextViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIPickerViewDelegate,UIPickerViewDataSource {
var countries = ["USA","UK","Spain" ]
var gender = ["Male","Female","Both"]
var language = ["English","French","Spanish","Other"]
override func viewDidLoad() {
super.viewDidLoad()
var pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 100))
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
var 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()
pickerView.delegate = self
pickerView.dataSource = self
[![enter image description here][1]][1]
var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "canclePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
genderTxt.inputView = pickerView
genderTxt.inputAccessoryView = toolBar
countriesTxt.inputView = pickerView
countriesTxt.inputAccessoryView = toolBar
categoriesTxt.inputView = pickerView
categoriesTxt.inputAccessoryView = toolBar
startDateTxt.inputView = pickerView
startDateTxt.inputAccessoryView = toolBar
endDateTxt.inputView = pickerView
endDateTxt.inputAccessoryView = toolBar
languageTxt.inputView = pickerView
languageTxt.inputAccessoryView = toolBar
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countries.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return countries[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
var itemselected = countries[row]
countriesTxt.text = itemselected
}
You don't need multiple UIPickerView. Instead you need to set picker view data source based on first responder text view. Also you should implement textFieldShouldBeginEditing delegate method to reload content of picker view by calling its reloadAllComponents method
var pickerView : UIPickerView!
override func viewDidLoad() {
self.pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 100))
NSNotificationCenter.defaultCenter().addObserver(self, selector: ("updatePicker"), name: UITextFieldTextDidBeginEditingNotification, object: nil)
}
func updatePicker(){
self.pickerView.reloadAllComponents()
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if countriesTxt.isFirstResponder(){
return countries.count
}else if genderTxt.isFirstResponder(){
return gender.count
}
// continue this way and implement all cases
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if countriesTxt.isFirstResponder(){
return countries[row]
}else if genderTxt.isFirstResponder(){
return gender[row]
}
// continue this way and implement all cases
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if countriesTxt.isFirstResponder(){
var itemselected = countries[row]
countriesTxt.text = itemselected
}else if genderTxt.isFirstResponder(){
var itemselected = gender[row]
genderTxt.text = itemselected
}
// ...
}
You should add booleans to know what kind of data you want to pick, then you should check these booleans to know the array you want to take the data from, and when you open the picker view assign the correct values:
import UIKit
class testVC: UIViewController,UITextViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate,UIPickerViewDelegate,UIPickerViewDataSource {
var countries = ["USA","UK","Spain" ]
var gender = ["Male","Female","Both"]
var language = ["English","French","Spanish","Other"]
var countriesFlag = true
var genderFlag = false
var languageFlag = false
override func viewDidLoad() {
super.viewDidLoad()
var pickerView = UIPickerView(frame: CGRectMake(0, 200, view.frame.width, 100))
pickerView.backgroundColor = .whiteColor()
pickerView.showsSelectionIndicator = true
var 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()
pickerView.delegate = self
pickerView.dataSource = self
[![enter image description here][1]][1]
var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "donePicker")
var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "canclePicker")
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
genderTxt.inputView = pickerView
genderTxt.inputAccessoryView = toolBar
countriesTxt.inputView = pickerView
countriesTxt.inputAccessoryView = toolBar
categoriesTxt.inputView = pickerView
categoriesTxt.inputAccessoryView = toolBar
startDateTxt.inputView = pickerView
startDateTxt.inputAccessoryView = toolBar
endDateTxt.inputView = pickerView
endDateTxt.inputAccessoryView = toolBar
languageTxt.inputView = pickerView
languageTxt.inputAccessoryView = toolBar
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
//Add this delegate to know the clicked textview
textViewDidBeginEditing(textView: UITextView) {
if textView == countriesTxt {
countriesFlag = true
genderFlag = false
languageFlag = false
} else if textView == genderTxt {
countriesFlag = false
genderFlag = true
languageFlag = false
} else {
countriesFlag = false
genderFlag = false
languageFlag = true
}
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if countriesFlag {
return countries.count
} else if genderFlag {
return gender.count
} else {
return language.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if countriesFlag {
return countries[row]
} else if genderFlag {
return gender[row]
} else {
return language[row]
}
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if countriesFlag {
var itemselected = countries[row]
countriesTxt.text = itemselected
} else if genderFlag {
var itemselected = gender[row]
genderTxt.text = itemselected
} else {
var itemselected = language[row]
languageTxt.text = itemselected
}
}
}