Using a picker view based on what has been selected before - ios

I looked on here for an answer, but do not believe this question has been answered. I have multiple text boxes that use a couple different pickers. I would like for the first text box the user selects the material, and then based on the material selected they can only see the type of material that corresponds to it. Below in my code when I am naming my arrays you can see that it says typeBrassData or typeCopperData so if the user selects Brass or Copper above only the options for Brass show, does anyone know how to do this? Below is the code I was using when it was only 2 picker views. Thanks all in advance!
import UIKit
class MetalCalculatorViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var materialField: UITextField!
#IBOutlet weak var typeField: UITextField!
#IBOutlet weak var volumeField: UITextField!
#IBOutlet weak var quantityField: UITextField!
var pickerMaterial = UIPickerView()
var pickerType = UIPickerView()
var materialData = ["Brass","Copper","CuNiSn", "Cupro-Nickel","High Performance Alloys", "Leaded Brass","Nickel Silvers","Phosphor Bronze","Tin Brass"]
var typeData = ["C101", "C102","C1092","C110","C122","C14415","C151", "C155","C18070", "C18080", "C19020", "C19025", "C19210","C194", "C195", "C197", "C1972", "C210","C220", "C226", "C230", "C240", "C260","C268","C272", "C350", "C353", "C422", "C425", "C4252", "C510","C511", "C5118", "C519","C521", "C638", "C654", "655", "C688", "C7025", "C70250", "C7026", "C7035", "C706", "C710", "C715", "C7250", "C752", "C757","C764","C770", "XP5", "XP10", "XP55", "XP125", "XP150", "XP175", "MAX251C", "MSP1"]
var typeBrassData = ["C210","C220", "C226", "C230", "C240", "C260","C268","C272"]
var typeHighPerformanceData = ["C14415","C151", "C155","C18070", "C18080", "C19020", "C19025", "C19210","C194", "C195", "C197", "C1972", "C638", "C654", "655", "C688", "C7025", "C70250", "C7026", "C7035", "XP5", "XP10", "XP55", "XP125", "XP150", "XP175", "MAX251C", "MSP1"]
var typeCopperData = ["C101", "C102","C1092","C110","C122"]
var typeCuproNickelData = ["C706", "C710", "C715"]
var typeLeadedBrassData = ["C350", "C353"]
var typeTinBrassData = ["C422", "C425", "C4252"]
var typePhosphorBronzeData = ["C510","C511", "C5118", "C519","C521"]
var typeCunNiSnData = ["C725"]
var typeNickelSilverData = ["C752", "C757","C764","C770"]
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
pickerMaterial.delegate = self
pickerMaterial.dataSource = self
pickerMaterial.tag = 1
materialField.inputView = pickerMaterial
pickerType.delegate = self
pickerType.dataSource = self
pickerType.tag = 2
typeField.inputView = pickerType
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MetalCalculatorViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
// Do any additional setup after loading the view.
}
func dismissKeyboard() {
view.endEditing(true)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == pickerMaterial {
return materialData.count
} else if pickerView == pickerType{
return typeData.count
}
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pickerMaterial {
return materialData[row]
} else if pickerView == pickerType{
return typeData[row]
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == pickerMaterial {
materialField.text = materialData[row]
} else if pickerView == pickerType{
typeField.text = typeData[row]
}
}

You can use the dictionary data structure to set the values of the pickerviews
var materialSelected = ""
var typeArr = [String]()
//I have done for only three materials obviously you can extend it...
var dict = ["Brass" : ["C210","C220", "C226", "C230", "C240", "C260","C268","C272"],
"Copper" : ["C101", "C102","C1092","C110","C122"], "CuNiSn" : ["C725"]] as [String: Any]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == pickerMaterial {
return materialData.count
} else if pickerView == pickerType{
typeArr = dict[materialSelected] as! [String]
return typeArr.count
}
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pickerMaterial {
return materialData[row]
} else if pickerView == pickerType{
typeArr = dict[materialSelected] as! [String]
return typeArr[row]
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == pickerMaterial {
materialSelected = materialData[row]
materialField.text = materialSelected
} else if pickerView == pickerType{
typeArr = dict[materialSelected] as! [String]
typeField.text = typeArr[row]
}
}

Related

I see only ?-s when using 2 pickerviews in Swift on the same view controller, how to fix this?

I have been trying to figure out this problem for hours, now I have only one small problem remaining:
I use 2 UI pickers on one view controller, and when I try to select one (aka I'm clicking into the textfield) all I see is question marks, but if I click on one of them, the text will appear in the textfield. I just don't see what am I choosing in the picker.
I already tried using normal pickerviews, I used tags for each pickers, but nothing seemed to work. I know how it should work, I watched a ton of tutorials, but something is still missing. Can you please help me? Thank you!
Here is the code:
import UIKit
class SelectionViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
#IBOutlet weak var ageTextField: UITextField!
#IBOutlet weak var weightTextField: UITextField!
#IBOutlet weak var genderTextField: UITextField!
#IBOutlet weak var lifeStyleTextField: UITextField!
let picker1 = UIPickerView()
let picker2 = UIPickerView()
var genders = ["Male", "Female"]
var lifeStyle = ["Sitting", "Normal", "Active"]
override func viewDidLoad() {
super.viewDidLoad()
picker1.dataSource = self
picker1.delegate = self
picker2.dataSource = self
picker2.delegate = self
genderTextField.inputView = picker1
lifeStyleTextField.inputView = picker2
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponentsInPickerView(pickerView : UIPickerView!) -> Int{
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
if pickerView == picker1 {
return genders.count
} else {
return lifeStyle.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if pickerView == picker1 {
return genders[row]
} else if pickerView == picker2{
return lifeStyle[row]
}
else {
print("No pickerview selected.")
}
return ("Pickeview not selected")
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == picker1 {
genderTextField.text = genders[row]
self.view.endEditing(false)
} else if pickerView == picker2{
lifeStyleTextField.text = lifeStyle[row]
self.view.endEditing(false)
}
else {
print("Love love love I want your love")
}
}
}
And here's the thing I see:
You need this signature ( missed _ )
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
and numberOfComponentsInPickerView should return 1

swift 4 multiple picker view not working. I have three arrays ,but only "strBlood" is showing

swift 4 multiple picker view not working. I have three arrays ,but only "strBlood" is showing the accurate array , other strcountry and strgender are not showing in the picker view and when I click on to the third label code crashes giving me the error of signal sigbart
multiple picker views are not showing the data in the picker view in swift 4, I already read many tutorials but no one solve my problem please check and answer me.
when I implemented 3 picker views the data is showing only of the first picker view i.e , (strblood) but not the other arrays
the code below is working properly but there is one error regarding showing the array in the picker view when clciked on the other labels ("lblblood"."lblcountry")
import UIKit
import Foundation
class RegisterViewController: UIViewController {
var strBlood = ["O+","O-","O","A","B+"]
var strcountry = ["India","Canada","USA"]
var strgender = ["Male","Female"]
var selectedBlood: String?
var selectedCountry: String?
var selectedGender: String?
#IBOutlet weak var txtGender: UITextField!
#IBOutlet weak var txtCountry: UITextField!
#IBOutlet weak var lblBloodGroup: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.chooseCountry()
self.chooseBlood()
self.choosGender()
}
func chooseBlood(){
let bloodPicker = UIPickerView()
bloodPicker.delegate = self
self.lblBloodGroup.inputView = bloodPicker
}
func chooseCountry(){
let countryname = UIPickerView()
countryname.delegate = self
self.txtCountry.inputView = countryname
}
func choosGender() {
let gender1 = UIPickerView()
gender1.delegate = self
self.txtGender.inputView = gender1
}
}
extension RegisterViewController : UIPickerViewDelegate , UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if lblBloodGroup.isEnabled {
print("BLOOD SELECTED")
return strBlood.count
}
else if txtCountry.isEnabled{
print("COUNTRY SELECTED")
return strcountry.count
}else {
print("GENDER SELECTED")
return strgender.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if lblBloodGroup.isEnabled{
print("BLOOD SELECTED1")
return strBlood[row]
}else if txtCountry.isEnabled{
return strcountry[row]
}else {
return strgender[row]
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if lblBloodGroup.isEnabled{
selectedBlood = strBlood[row]
lblBloodGroup.text = selectedBlood
}else if txtCountry.isEnabled{
selectedCountry = strcountry[row]
txtCountry.text = selectedCountry
}else {
selectedGender = strgender[row]
txtGender.text = selectedGender
}
}
}
To achieve this isEnabled will not help. you need to use isEditing and it will be true if user click on any UITextField and your code will be:
import UIKit
import Foundation
class ViewController: UIViewController {
var strBlood = ["O+","O-","O","A","B+"]
var strcountry = ["India","Canada","USA"]
var strgender = ["Male","Female"]
var selectedBlood: String?
var selectedCountry: String?
var selectedGender: String?
#IBOutlet weak var txtGender: UITextField!
#IBOutlet weak var txtCountry: UITextField!
#IBOutlet weak var lblBloodGroup: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.chooseCountry()
self.chooseBlood()
self.choosGender()
}
func chooseBlood(){
let bloodPicker = UIPickerView()
bloodPicker.delegate = self
self.lblBloodGroup.inputView = bloodPicker
}
func chooseCountry(){
let countryname = UIPickerView()
countryname.delegate = self
self.txtCountry.inputView = countryname
}
func choosGender() {
let gender1 = UIPickerView()
gender1.delegate = self
self.txtGender.inputView = gender1
}
}
extension ViewController : UIPickerViewDelegate , UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if lblBloodGroup.isEditing {
print("BLOOD SELECTED")
return strBlood.count
}
else if txtCountry.isEditing{
print("COUNTRY SELECTED")
return strcountry.count
}else {
print("GENDER SELECTED")
return strgender.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if lblBloodGroup.isEditing{
print("BLOOD SELECTED1")
return strBlood[row]
}else if txtCountry.isEditing{
return strcountry[row]
}else {
return strgender[row]
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if lblBloodGroup.isEditing{
selectedBlood = strBlood[row]
lblBloodGroup.text = selectedBlood
}else if txtCountry.isEditing{
selectedCountry = strcountry[row]
txtCountry.text = selectedCountry
}else {
selectedGender = strgender[row]
txtGender.text = selectedGender
}
}
}
And result will be:

How to use 2 UIPickerViews in the same view controller? [duplicate]

This question already has an answer here:
How to distinguish between multiple uipickerviews on one page
(1 answer)
Closed 5 years ago.
My code below uses a UIPickerView and works perfectly. However I do not know how to repeat this process for 2 different picker views that each contain separate information. l2 and pl2 are the 2nd picker view and label.
import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate{
#IBOutlet var l: UILabel!
#IBOutlet var pl: UIPickerView!
#IBOutlet var l2: UILabel!
#IBOutlet var pl2: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
pl.dataSource = self
pl.delegate = self
pl2.dataSource = self
pl2.delegate = self
}
let choices = ["1","2","3","4","5","6","7","8","9","10","11"]
let choices2 = ["1","judo","3","4","5","6","7","8","9","10","11"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pl {
return choices[row]
} else if pickerView == pl2 {
return choices2[row]
} else {
return nil
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return choices.count
return choices2.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == pl {
l.text = choices[row]
} else if pickerView == pl2 {
l2.text = choices2[row]
}
}
}
You have a reference to your UIPickerView in the delegate methods so you can do code like :
func numberOfComponents(in pickerView: UIPickerView) -> Int {
if(pickerView == pl) {
//pl specific code
}
if(pickerView == pl2) {
//pl2 specific code
}
}
And do that for every method.
You have to set up your ViewController as the DataSource and Delegate of pl2 as well and in the delegate and datasource methods you should filter for the UIPickerView.
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate{
#IBOutlet var l: UILabel!
#IBOutlet var pl: UIPickerView!
#IBOutlet var l2: UILabel!
#IBOutlet var pl2: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
pl.dataSource = self
pl.delegate = self
pl2.dataSource = self
pl2.delegate = self
}
let choices = ["1","2","3","4","5","6","7","8","9","10","11"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == pl1 {
return choices[row]
} else if pickerView == pl2 {
return choices2[row] //or whatever you want to use as the dataSource for pl2
} else {
return nil
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
//do the same as above
return choices.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
//do the same as above
l.text = choices[row]
}
}

Multiple Custom UIPickerViews in the same UIView in swift

Im trying to have two different pickerViews on the same viewController and let them represent different data. I have tried a different ways to do this, but both picker views showing same Data, but can't put it all together. Any help would be awesome!
here is my code:
#IBOutlet weak var Eventtype: UITextField!
let pickerView = UIPickerView()
var Eventstype = ["Birthday" , "Marriege" , "Get together", "Conference"]
#IBOutlet weak var datepickertxt: UITextField!
var datepicker = UIDatePicker()
#IBOutlet weak var Duration: UITextField!
let duration = UIPickerView()
var Durations = ["6-8","1-5","7-9","10-12"]
override func viewDidLoad() {
super.viewDidLoad()
createDatePicker()
pickerView.delegate = self
pickerView.dataSource = self
duration.delegate = self
duration.dataSource = self
Eventtype.inputView = pickerView
Duration.inputView = duration
// Do any additional setup after loading the view.
}
////For Event Picker view
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (pickerView.tag == 0) {
//pickerView1
return Eventstype.count
} else if (duration.tag == 1){
//pickerView2
return Durations.count
}
return 1
//return DurationTxt.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if (pickerView.tag == 0) {
return Eventstype[row]
} else if (duration.tag == 1){
return Durations[row]
}
return ""
}
//return DurationTxt[row]
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (pickerView.tag == 0) {
Eventtype.text = Eventstype[row]
self.view.endEditing(false)
}else if (duration.tag == 1){
Duration.text = Durations[row]
self.view.endEditing(true)
}
}
#IBOutlet weak var Eventtype: UITextField!
let pickerView = UIPickerView()
var Eventstype = ["Birthday" , "Marriege" , "Get together", "Conference"]
#IBOutlet weak var datepickertxt: UITextField!
var datepicker = UIDatePicker()
#IBOutlet weak var Duration: UITextField!
let duration = UIPickerView()
var Durations = ["6-8","1-5","7-9","10-12"]
override func viewDidLoad() {
super.viewDidLoad()
createDatePicker()
pickerView.delegate = self
pickerView.dataSource = self
duration.delegate = self
duration.dataSource = self
Eventtype.inputView = pickerView
Duration.inputView = duration
pickerView.tag = 0
duration.tag = 1
// Do any additional setup after loading the view.
}
////For Event Picker view
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (pickerView.tag == 0) {
//pickerView1
return Eventstype.count
} else if (duration.tag == 1){
//pickerView2
return Durations.count
}
return 1
//return DurationTxt.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if (pickerView.tag == 0) {
return Eventstype[row]
} else if (duration.tag == 1){
return Durations[row]
}
return ""
}
//return DurationTxt[row]
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (pickerView.tag == 0) {
Eventtype.text = Eventstype[row]
self.view.endEditing(false)
}else if (duration.tag == 1){
Duration.text = Durations[row]
self.view.endEditing(true)
}
}
This is done by tag or else yo can check in delegate like
if pickerView == duration
Set the tags for pickerview in viewDidLoad as shown below,
pickerView.tag = 0
duration.tag = 1
class ViewController: UIViewController {
#IBOutlet var txtDuration: UITextField!
#IBOutlet var txtEventType: UITextField!
var pickerView = UIPickerView()
var arrEventType : [String] = []
var arrDuration : [String] = []
var currentTextField : UITextField?
override func viewDidLoad() {
super.viewDidLoad()
arrEventType = ["Birthday" , "Marriage" , "Get together", "Conference"]
arrDuration = ["6-8","1-5","7-9","10-12"]
}
}
extension ViewController : UIPickerViewDelegate , UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if currentTextField == txtEventType {
return arrEventType.count
} else if currentTextField == txtDuration {
return arrDuration.count
} else {
return 0
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if currentTextField == txtEventType {
return arrEventType[row]
} else if currentTextField == txtDuration {
return arrDuration[row]
} else {
return ""
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if currentTextField == txtEventType {
txtEventType.text = arrEventType[row]
} else if currentTextField == txtDuration {
txtDuration.text = arrDuration[row]
}
}
}
extension ViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.pickerView.delegate = self
self.pickerView.dataSource = self
currentTextField = textField
if currentTextField == txtEventType {
currentTextField?.inputView = pickerView
} else if currentTextField == txtDuration {
currentTextField?.inputView = pickerView
}
}
}
Above lines of code may solve your issue with just one UIPickerView and without tags

How to create multiple pickerviews programmatically

I am trying to create a separate pickerview for each textbox that is selected. so far the closest I have gotten is having the same pickerview for each of the text boxes that need their own separate list of items to choose from.
class MainViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
var dogBreedPickerArray = ["German Shepherd", "Huskie", "cray cray"]
var catBreedPickerArray = ["savanna", "cheetoh", "bengal"]
var maleFemalePickerArray = ["Male", "Female"]
var dogBreedPicker = UIPickerView()
var dogBreedPicker = UIPickerView()
var catBreedPicker = UIPickerView()
var maleFemalePicker = UIPickerView()
#IBOutlet var dogBreedTextBox: UITextField!
#IBOutlet var catBreedTextBox: UITextField!
#IBOutlet var maleFemaleTextBox: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
dogBreedPicker.delegate = self
dogBreedPicker.dataSource = self
dogBreedTextBox.inputView = dogBreedPicker
dogBreedTextBox.delegate = self
}
// dog picker functions
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return dogBreedPickerArray.count
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
petBreedTextBox.text = dogBreedPickerArray[row]
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return dogBreedPickerArray[row]
}
}
its just a example may be it help to you
after selecting any text field asign textfield tag to picker and reload the component.
// variable
var heightInch:[Int] = [Int]()
var heightfeet:[Int] = [Int]()
var heightCms:[Int] = [Int]()
delegate methods
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
if picker.tag == 1{
return 2
}else{
return 1
}
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if picker.tag == 1{
switch component {
case 0:
return heightfeet.count
default:
return heightInch.count
}
}else{
return heightCms.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if picker.tag == 1{
switch component {
case 0:
return String(heightfeet[row])
default:
return String(heightInch[row])
}
}else{
return String(heightCms[row])
}

Resources