Update UIPickerView rows when selecting new UITextField - swift

I have created a pickerView that uses 3 different arrays to populate 3 textfields but when I tap on one textfield, select a row, and then directly tap another textfield, my pickerView does not update to the information in the array for that textfield.
If I tap on a textfield then tap away to dismiss the pickerview and then tap another textfield it updates and works fine.
var teams = [String]()
var schedules = ["A","B"]
var services = ["9AM","12PM","5PM"]
var pickerView:UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
teamTextField.inputView = self.pickerView
serviceTextField.inputView = self.pickerView
scheduleTextField.inputView = self.pickerView
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if teamTextField.isFirstResponder() {
return teams.count
}
else if scheduleTextField.isFirstResponder() {
return schedules.count
}
else {
return services.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if teamTextField.isFirstResponder() {
return teams[row]
}
else if scheduleTextField.isFirstResponder() {
return schedules[row]
}
else {
return services[row]
}
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if teamTextField.isFirstResponder() {
let itemSelected = teams[row]
teamTextField.text = itemSelected
}
else if scheduleTextField.isFirstResponder() {
let itemSelected = schedules[row]
scheduleTextField.text = itemSelected
}
else if serviceTextField.isFirstResponder() {
let itemSelected = services[row]
serviceTextField.text = itemSelected
}
}
func textFieldDidBeginEditing(textField: UITextField) {
pickerView.reloadAllComponents()
}
That should be all the necessary code you need. If you need anything else, let me know.

Try to add this:
#IBAction func textFieldDidBeginEditing(sender: AnyObject) {
pickerView.reloadAllComponents()
}
and connect it to the 'Editing Did Begin' sent events of your UITextField's

Related

PickerView will reload by itself with wrong behavior Swift 4.2

My pickerView was going very well, but don't know why just get wrong behavior after rebuild the project folder.
The component[0] will reload itself but I didn't write any code for it!
Below are the codes:
DropdownListExtension.swift
extension UITextField: UITextFieldDelegate {
func loadAddressDropdownData(data: [String], zipField: UITextField!) {
self.inputView = AddressPickerView(pickerData: data, cityField: self, zipField: zipField)
// ToolBar
let toolBar = UIToolbar()
// Adding Button ToolBar
// ...Init ToolBar
self.inputAccessoryView = toolBar
}
#objc func doneClick() {
self.resignFirstResponder()
}
#objc func cancelClick() {
self.resignFirstResponder()
}
}
AddressPickerView.swift
class AddressPickerView : UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
var pickerData : [String]!
var pickerTextField : UITextField!
var zipTextField: UITextField!
var selectedRow = 0
var selectedCity = "臺北市"
init(pickerData: [String], cityField: UITextField, zipField: UITextField) {
super.init(frame: CGRect.zero)
self.pickerData = pickerData
self.pickerTextField = cityField
self.zipTextField = zipField
self.delegate = self
self.dataSource = self
DispatchQueue.main.async{
if pickerData.count > 0 {
self.pickerTextField.text = self.pickerData[0]
} else {
self.pickerTextField.text = nil
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0{
return pickerData.count
}else {
switch selectedCity{
//...
default:
return 0
}
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0{
return pickerData[row]
} else {
switch selectedCity{
//...
default:
return ""
}
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(component)
if component == 0 {
pickerTextField.text = pickerData[row]
selectedRow = row
selectedCity = pickerData[row]
pickerView.reloadComponent(1)
}else {
switch selectedCity{
case "臺北市":
zipTextField.text = taipei[row]
case "基隆市":
zipTextField.text = keelung[row]
//...
default:
return print("")
}
}
}
}
Please help me for fix it, I spent almost 3 das but still cannot figure out the problem...

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
}

result from multiple UIPickers

I work in a project that has two pickers and one button.
When the user chooses from the first and second pickers
he click on the button .. and show the result in the textfield ..
for example:
if he chooses from the first picker "Jed" and from the second picker "Ahmed"..
now if he clicks the button the result will be in the textfield shown "OK" ..
this is what I did so far .. I don't know why its crashing when I click on the button ..
import UIKit
class ViewController: UIViewController , UIPickerViewDelegate , UIPickerViewDataSource {
#IBOutlet weak var theResult: UITextField!
#IBOutlet weak var cityTxt2: UITextField!
#IBOutlet weak var cityTxt: UITextField!
var city = ["Jed" , "Med" , "Ruh"]
var city2 = ["ahmed" , "mohammed" , "mustafa"]
let picker = UIPickerView()
let picker2 = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
picker.dataSource = self
picker2.delegate = self
picker2.dataSource = self
cityTxt.inputView = picker
cityTxt2.inputView = picker2
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int{
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
if (pickerView == self.picker) {
return city.count
}
else if (pickerView == self.picker2) {
return city2.count
}
return city.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if (pickerView == self.picker) {
return city[row]
}
else if (pickerView == self.picker2) {
return city2[row]
}
return city[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (pickerView == picker) {
self.cityTxt.text = self.city[row]
}
else if (pickerView == picker2) {
self.cityTxt2.text = self.city2[row]
}
self.view.endEditing(false)
}
#IBAction func getTheResult(_ sender: Any) {
let R1 = cityTxt.text
let R2 = cityTxt2.text
if (R1 == "Jed") && (R2 == "ahmed"){
theResult.text = "OK"
}else{
theResult.text = ""
}
}
}
I think the problem is in the Button
because when I click on it .. the program will crash ..

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!

Accessing a variable stored within a class Swift

I can't figure out why I can't access this variable, see below, I want the value of sport result when it's clicked, however sportResult.selectedSport returns nil?
let sportPickerData = SportPickerData()
override func viewDidLoad() {
super.viewDidLoad()
sportPickerView.delegate = sportPickerData
sportPickerView.dataSource = sportPickerData
class SportPickerData: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
var sports = ["Football", "Baseball", "Hockey", "Basketball"]
var selectedSport: String?
func numberOfComponentsInPickerView(yearPicker: UIPickerView) -> Int {
return 1
}
func pickerView(yearPicker: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return sports.count
}
func pickerView(yearPicker: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedSport = sports[row]
}
func pickerView(yearPicker: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return "\(sports[row])"
}
}
let sportResult = SportPickerData()
#IBAction func button(sender: UIButton) {
label.text = sportResult.selectedSport
}
sportResult its not a delegate or a data source of your picker view so its selectedSport property will never be initialized since its didSelectRow method will be never called. To get the selectedSport you have to get it from sportPickerData which is actually the delegate and data source of your picker
let sportResult = SportPickerData() // delete this line
#IBAction func button(sender: UIButton) {
label.text = sportPickerData.selectedSport
}