How to compare selected UIPickerView row element to Array element? - ios

import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var categoryFactsPincker: UIPickerView!
#IBOutlet weak var randomFactLabel: UILabel!
This is my array of my UIPickerView
let categoryFactsArray = ["Interesting Facts", "Fun Facts", "Nutrition Facts", "Funny Facts", "Unbelievable Facts", "Did You Know", "Animal Facts", "Mind Blowing Facts", "Weird Facts"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
categoryFactsPincker.delegate = self
categoryFactsPincker.dataSource = self
}
I would like to use this button to compare array element and UIPickerView selected for print different categories
#IBAction func buttonPressed(_ sender: UIButton) {
if categoryFactsArray[row] == 0 {
updateInterestingFacts()
}else if categoryFactsPincker.selectedRow(inComponent: 1){
}
}
func updateInterestingFacts(){
let random = interestingFactsArray[Int(arc4random_uniform(UInt32(interestingFactsArray.count)))]
// randomFactLabel.text = random
let alert = UIAlertController(title: "Random Fact", message: "\(random)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return categoryFactsArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return categoryFactsArray[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
categoryFactsArray[row]
}
}

try this
#IBAction func buttonPressed(_ sender: UIButton) {
if categoryFactsPincker.selectedRow(inComponent: 0) == 0 {
updateInterestingFacts()
}else{
let categorySelected = categoryFactsArray[categoryFactsPincker.selectedRow(inComponent: 0)]
print(categorySelected)
}
}
this print should show the selected value, so you can use to compare, or whatever you need

At the end I fixed it with this code:
#IBAction func buttonPressed(_ sender: UIButton) {
if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 0 {
updateInterestingFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 1 {
updateFunFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 2{
updateNutritionFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 3{
updateFunnyFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 4{
updateUnbelievableFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 5{
updateDidYouKnowFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 6{
updateAnimalFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 7{
updateMindBlowingFacts()
}else if Int(categoryFactsPincker.selectedRow(inComponent: 0)) == 8{
updateWeirdFacts()
}
}

Related

UITextfield as float passed through segue to an UILabel

Im fairly new to swift and would like for a user to enter a number using the decimal pad for UITextfield to enter a float then pass that float to another view controller using a UILabel. Everything works except passing the float to the UILabel on the other view controller. I get this error
"Cannot assign value of type 'UITextField?' to type 'UILabel?'"
import UIKit
class SelectAttributesViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
#IBOutlet weak var kitPickerView: UIPickerView!
#IBOutlet weak var reactionVolumeLabel: UILabel!
#IBOutlet weak var numberOfSampleTextField: UITextField!
#IBOutlet weak var volumeOfTemplateDNATextField: UITextField!
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var calculateButton: UIButton!
let kits = ["kit 1", "Kit 2"]
let pArray = [10,20,50]
override func viewDidLoad() {
super.viewDidLoad()
self.numberOfSampleTextField.delegate = self
self.volumeOfTemplateDNATextField.delegate = self
kitPickerView.dataSource = self
kitPickerView.delegate = self
let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))
view.addGestureRecognizer(tap)
}
func pSliderInterval() {
slider.minimumValue = 0
slider.maximumValue = Float(pArray.count)
slider.isContinuous = false
}
#IBAction func reactionVolumeSlider(_ sender: UISlider) {
print(Int(sender.value))
let currentValue = pArray[Int(sender.value)]
reactionVolumeLabel.text = "\(currentValue) "
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return kits.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if row == 0{ print(kits[row])
}else if row == 1{
createAlert(title: "Kit not available", message: "More kits will be added soon!")
calculateButton.isEnabled = false
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return kits[row]
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let oldText = textField.text, let r = Range(range, in: oldText) else {
return true
}
let newText = oldText.replacingCharacters(in: r, with: string)
let isNumeric = newText.isEmpty || (Double(newText) != nil)
let numberOfDots = newText.components(separatedBy: ".").count - 1
let numberOfDecimalDigits: Int
if let dotIndex = newText.firstIndex(of: ".") {
numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
} else {
numberOfDecimalDigits = 0
}
return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2
}
func createAlert (title: String, message: String){
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: { (Action) in
alert.dismiss(animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)
}
// This is the Segue.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var masterMix = segue.destination as! MasterMixTableViewController
masterMix.waterVolumeLabel = numberOfSampleTextField
}
#IBAction func calculatePressed(_ sender: Any) {
if numberOfSampleTextField.text != ""{
performSegue(withIdentifier: "masterMixSegue", sender: self)
}
}
}
I have browsed heavily for the solution but haven't found anything.
You need
let masterMix = segue.destination as! MasterMixTableViewController
masterMix.loadViewIfNeeded()
masterMix.waterVolumeLabel!.text = numberOfSampleTextField!.text
The error says you are assigning UITextField to UILabel. But you must assign textFeild.text to label.text.
let textField = UITextField()
let label = UILabel()
label.text = textField.text

Thread 1: Fatal error: Index out of range on swift 4

I have a issue on Thread 1 fatal error on my code. I try to create 2 pickers in one view controller. But the error keep coming. When I tried to run on my phone, everything is okay till this page (picker cannot move). It shows an error on (return subject[row]) on 6 line from bottom)
enter image description here
Heres my code:
Import UIKit
class ThirdViewController: UIViewController, UIPickerViewDelegate,
UIPickerViewDataSource {
#IBOutlet weak var classPickerView: UIPickerView!
#IBOutlet weak var subjectPickerView: UIPickerView!
#IBOutlet weak var nextButton: UIButton!
let subclass = ["AA234", "ASA231", "AA9292", "AAA839", "AA5682", "AAA789"]
let subject = ["Introduction to Database","Introduction to Programming","Mathematics","Multimedia"]
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func buttonPressed(_ sender: Any) {
let picker = UIImagePickerController()
picker.delegate = (self as! UIImagePickerControllerDelegate & UINavigationControllerDelegate)
//select row first
let selectedRow1 = classPickerView.selectedRow(inComponent: 0)
let selectedRow2 = subjectPickerView.selectedRow(inComponent: 0)
let selectedClass = subclass [selectedRow1]
let selectedSubClass = subject [selectedRow2]
let messageToShow = "Class \(selectedClass) with the subject \(selectedSubClass)"
// insert messageToShow in message to appear what u selected
let actionSheet = UIAlertController (title: "Please Confirm Before Scan", message: messageToShow, preferredStyle: .alert)
let okAction = UIAlertAction (title: "Proceed to Scan", style: .default, handler: nil) //{action in
//picker.sourceType = .camera})
let cancelAction = UIAlertAction (title: "Cancel", style: .cancel, handler: nil)
actionSheet.addAction(okAction)
actionSheet.addAction(cancelAction)
present(actionSheet, animated: true, completion: nil)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (pickerView.tag == 1) {
return subject.count
}
else {
return subclass.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return subject[row]
}
else {
return subclass[row]
}
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (component == 0) {
return subject.count
}
else {
return subclass.count
}
}
Change numberOfRowsInComponent code as above

Choose which ViewController to switch to by using Picker View

I am creating a restaurant app, in which the user could select which restaurant they would like to do on the first screen. After they've made their selection the user should press the begin button and it will take it to that View Controller
I have no idea how to get started, any help would be appreciated.
Set label text in picker didselect delegate . then on button action method decide which vc to open on the basis of label text.
Used button action is Done Button that we embed with picker to make final selection.
Use the following code: Works fine
import UIKit
class PickerViewController: UIViewController,UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var pickerVieww: UIPickerView!
var viewControllerArray = [String]()
var value = Int()
override func viewDidLoad() {
super.viewDidLoad()
pickerVieww.delegate = self
pickerVieww.dataSource = self
viewControllerArray = ["controller1","controller2","controller3"]
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return viewControllerArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return viewControllerArray[row]
}
func pickerView(_ pickerView: UIPickerView,didSelectRow row: Int,inComponent component: Int)
{
if(row == 0) {
value = 0
}
else if(row == 1) {
value = 1
}
else{
value = 2
}
}
#IBAction func swicthToController(_ sender: Any) {
if value == 0{
let vc = self.storyboard?.instantiateViewController(withIdentifier: "first") as! asasasViewController
self.present(vc, animated: true, completion: nil)
}
if value == 1{
let vc = self.storyboard?.instantiateViewController(withIdentifier: "second") as! secondViewController
self.present(vc, animated: true, completion: nil)
}
if value == 2{
let vc = self.storyboard?.instantiateViewController(withIdentifier: "third") as! thirdViewController
self.present(vc, animated: true, completion: nil)
}
}
}

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

picker view with button to go to next page

I'm trying to do a pickerView and a button which when you choose your option in pickerView it goes to the relevant page.
So far I've got to the point when you choose the option in picker view it goes to the relevant page, but what I want is choose and then click on the button to go to the page.
import UIKit
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var pickerView: UIPickerView!
var selection = ["Page 1", "Page 2", "Page 3"]
override func viewDidLoad() {
super.viewDidLoad()
pickerView.dataSource = self
pickerView.delegate = self
}
#IBAction func SelectionBtn(_ sender: Any) {
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return selection.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let selected = selection[row]
return selected
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (row == 0) {
performSegue(withIdentifier: "red", sender: self)
}
else if (row == 1) {
performSegue(withIdentifier: "blue", sender: self)
}
else {
performSegue(withIdentifier: "green", sender: self)
}
}
}
Take an extra variable to store information on regarding which row you have selected.
var rowSelected:Int! = -1
Store the selected row to this variable.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
rowSelected = row
}
During button action check the variable to perform desired Segue.
#IBAction func actSegue(sender:Any){
if row == 0 {
performSegue(withIdentifier: "red", sender: self)
}...
....
}
You can get the row selected with :pickerView.selectedRow(inComponent: 0)
#IBAction func SelectionBtn(_ sender: Any) {
let rowSelected = pickerView.selectedRow(inComponent: 0)
if (rowSelected == 0) {
performSegue(withIdentifier: "red", sender: self)
}
else if (rowSelected == 1) {
performSegue(withIdentifier: "blue", sender: self)
}
else {
performSegue(withIdentifier: "green", sender: self)
}
}

Resources