result from multiple UIPickers - swift

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 ..

Related

How to assign numbers for each UIpicker row

I am trying to develop a function in which the user enters a number in a TextField and based on the selection of the picker, it will calculate the number and display it either in a label or another text field. Now keep in mind, the picker has to retain String titles, but it will have different numbers for each row.
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate,
UIPickerViewDataSource {
#IBOutlet weak var numberInput: UITextField!
#IBOutlet weak var pickerControl: UIPickerView!
#IBOutlet weak var pickerControl2: UIPickerView!
#IBOutlet weak var resultField: UILabel!
var pickerData = ["Logistic","Administration","Clinic"]
var pickerData2 = ["Days","Weeks","Months"]
override func viewDidLoad() {
super.viewDidLoad()
pickerControl.delegate = self
pickerControl2.delegate = self
pickerControl.delegate = self
pickerControl2.delegate = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView,
numberOfRowsInComponent component: Int) -> Int {
if pickerView == pickerControl {
return pickerData.count
} else if pickerView == pickerControl2 {
return pickerData2.count
}
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row:
Int, forComponent component: Int) -> String? {
if pickerView == pickerControl {
return pickerData[row]
} else if pickerView == pickerControl2 {
return pickerData2[row]
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row:
Int, inComponent component: Int) -> String? {
let entry = Float(numberInput.text!) ?? 0.0
if pickerView == pickerControl {
return (Array(pickerData)[row])
}
if pickerView == pickerControl2 {
if Array(pickerData2)[row] == "Days" {
self.resultField.text = String(entry * 3)
}
if Array(pickerData2)[row] == "Weeks" {
self.resultField.text = String(entry * 4)
}
if Array(pickerData2)[row] == "Months" {
self.resultField.text = String(entry * 6)
}
return Array(pickerData2)[row]
}
return ""
}
}
The function signature for pickerView(didSelect...) isn't correct, so it's not getting called. You'll see that Xcode is giving you a warning about it. That function shouldn't be returning anything.
Here's an example of how to change it:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let entry = Float(numberInput.text ?? "") ?? 0.0
if pickerView == pickerControl {
return
}
switch pickerData2[row] {
case "Days":
self.resultField.text = String(entry * 3)
case "Weeks":
self.resultField.text = String(entry * 4)
case "Months":
self.resultField.text = String(entry * 6)
default:
break
}
}
You'll note that I also used a switch statement, which I think is a little cleaner looking. But, if you didn't and stuck to your if/else, you don't have to use Array() for everything -- you can do things like if pickerControl2[row] == "Days" { }
You could clean things up even further by defining pickerData2 as:
var pickerData2 : [(title: String, value: Float)] = [(title: "Days",value: 3),(title: "Weeks",value: 4),(title: "Months", value:6)]
Then, in titleForRow, you could return pickerData2[row].title
and later, in didSelectRow:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let entry = Float(numberInput.text ?? "") ?? 0.0
if pickerView == pickerControl {
return
}
self.resultField.text = String(entry * pickerData2[row].value)
}

multiple pickerview didSelectRow error in Swift

I have 2 pickerviews, 1 pickerview is to select a crypto-currency from an Array and the other pickerview is used to select a currency from an array. The problem I am having is when I run the app on simulator and select the cryptocurreny in cryptoPicker the app it also selects the same array value from currencyPicker and vice a versa. I don't want the array value of 0 to be pulled from both arrays unless it is selected by the user.
#IBOutlet weak var cryptoCurrentRate: UILabel!
#IBOutlet weak var currencyLabel: UILabel!
#IBOutlet weak var currencyPicker: UIPickerView!
#IBOutlet weak var cryptoPicker: UIPickerView!
#IBOutlet weak var cryptoLabel: UILabel!
var coinManager = CoinManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
coinManager.delegate = self
currencyPicker.dataSource = self
currencyPicker.delegate = self
cryptoPicker.dataSource = self
cryptoPicker.delegate = self
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == currencyPicker {
return coinManager.currencyArray.count
}
if pickerView == cryptoPicker {
return coinManager.cryptoArray.count
}
return 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == currencyPicker {
return coinManager.currencyArray[row]
}
if pickerView == cryptoPicker {
return coinManager.cryptoArray[row]
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let selectedCurrency = coinManager.currencyArray[row]
let selectedCrypto = coinManager.cryptoArray[row]
coinManager.fetchCryptoCoin(assetIdBase: selectedCrypto, assetIdQuote: selectedCurrency)
}
}
Do the same check for picker and in 'didSelectRow', you can do it like this:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
var selectedCurrency: CurrencyModel? = nil
var selectedCrypt: CryptModel? = nil
if pickerView == currencyPicker {
selectedCurrency = coinManager.currencyArray[row]
}
if pickerView == cryptoPicker {
selectedCrypto = coinManager.cryptoArray[row]
}
coinManager.fetchCryptoCoin(assetIdBase: selectedCrypt == nil ? coinManager.cryptoArray[.zero] : selectedCrypt!, assetIdQuote: selectedCurrency == nil ? coinManager.currencyArray[.zero] : selectedCurrency!)
}
By default it will get the first value from 'coinManager.currencyArray' or 'coinManager.cryptoArray'

How to use multiple UIPickerViews in one view controller

I am trying to set up 2 UIPickerViews in 1 view controller. I have not been able to find resources that solve my problem.
I have tried following the answer from Diavel Rider on How to use 2 UIPickerView's in one View Controller?. I got some errors from that. I have also tried adding tags but was not able to successfully do that. I am using Swift 4.
Here is the code of my view controller:
import UIKit
class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ foodTypeUIPickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
var countrows : Int = nutritionPickerData.count
if pickerView == foodTypeUIPickerView { **[Error Here: "Binary operator '==' cannot be applied to operands of type '_' and 'UIPickerView'"]**
countrows = self.foodTypePickerData.count
}
return countrows
}
func pickerView(_ foodTypeUIPickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == nutritionUIPickerView { **[Error Here: "Binary operator '==' cannot be applied to operands of type '_' and 'UIPickerView'"]**
let titleRow = nutritionPickerData[row]
return titleRow
} else if pickerView == foodTypeUIPickerView { **[Error Here: "Binary operator '==' cannot be applied to operands of type '_' and 'UIPickerView'"]**
let titleRow = foodTypePickerData[row]
return titleRow
}
return ""
}
#IBOutlet weak var nutritionUIPickerView: UIPickerView!
#IBOutlet weak var foodTypeUIPickerView: UIPickerView!
var nutritionPickerData = ["Protein", "Fiber", "Iron", "Fat", "Sodium", "Calcium/Vitamin D", "Energy", "Carbohydrates", "Cholestorol"]
var foodTypePickerData = ["Fruits", "Vegetables", "Legumes and Beans", "Grain", "Meat", "Dairy"]
#IBAction func submitUIButton(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.nutritionUIPickerView.delegate = self
self.nutritionUIPickerView.dataSource = self
self.foodTypeUIPickerView.delegate = self
self.foodTypeUIPickerView.dataSource = self
}
}
I need to use 2 picker views in 1 view controller. How do I do this?
You are referencing a non-existent variable named pickerView. You should update the parameter name to pickerView to avoid issues.
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == foodTypeUIPickerView {
return self.foodTypePickerData.count
} else {
return self. nutritionPickerData.count
}
}
Make a similar change to the other delegate/data source methods.
You should separate your data sources and delegates and not put them inside your view controller. Set those as the delegate and datasource. Code written in swift 4.2 xcode 10.1
class ViewController: UIViewController {
#IBOutlet weak var foodPicker: UIPickerView!
#IBOutlet weak var nutritionPicker: UIPickerView!
var foodData = FoodData()
var nutritionData = NutritionData()
override func viewDidLoad() {
super.viewDidLoad()
foodPicker.delegate = foodData
foodPicker.dataSource = foodData
nutritionPicker.delegate = nutritionData
nutritionPicker.dataSource = nutritionData
}
#IBAction func actionButton(_ sender: UIButton) {
let food = foodPicker.delegate?.pickerView!(foodPicker, titleForRow: foodPicker.selectedRow(inComponent: 0), forComponent: 0)
let nutrition = nutritionPicker.delegate?.pickerView!(nutritionPicker, titleForRow: nutritionPicker.selectedRow(inComponent: 0), forComponent: 0)
print("You picked: \(food) and \(nutrition)")
}
}
class FoodData: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
var foodTypePickerData = ["Fruits", "Vegetables", "Legumes and Beans", "Grain", "Meat", "Dairy"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return foodTypePickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return foodTypePickerData[row]
}
}
class NutritionData: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
var nutritionPickerData = ["Protein", "Fiber", "Iron", "Fat", "Sodium", "Calcium/Vitamin D", "Energy", "Carbohydrates", "Cholestorol"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return nutritionPickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return nutritionPickerData[row]
}
}

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
}

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!