Multiple pickerviews in single viewController - ios

Is it possible to have a single pickerView in swift which changes its value based on the button pressed. I could not figure out a way to implement more than one parameter through pickerView in a single ViewController. An alternative solution like a dropdown menu is fine too. Example/functional code would be great if provided. This is for a quiz app which would take multiple parameters.
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var selectionBtn: UIButton!
let animals = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
override func viewDidLoad() {
pickerView.isHidden = true
pickerView.delegate = self
pickerView.dataSource = self
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func selectPressed(_ sender: UIButton) {
if pickerView.isHidden {
pickerView.isHidden = false
}
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return animals.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return animals[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectionBtn.setTitle(animals[row], for: .normal)
pickerView.isHidden = true
}
}

Yes by having more than 1 data source
let animals1 = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
let animals2 = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
var mainData = [String]()
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return mainData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, fo rComponent component: Int) -> String? {
return mainData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectionBtn.setTitle(mainData[row], for: .normal)
pickerView.isHidden = true
}
assign mainData to say animal1
and reload
pickerView.reloadAllComponents()

Keep a separate array and put your array into it according to your logic. Use that array in pickerview. Try This:
let animals = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
let secondAnimals = ["Lion1", "Dog1", "Monkey1", "Cat1", "Bat1"]
let pickerArray = [String]()
#IBAction func selectPressed(_ sender: UIButton) {
pickerArray = animals //change it according to your logic
pickerView.reloadAllComponents()
pickerView.isHidden = !pickerView.isHidden
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerArray[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectionBtn.setTitle(pickerArray[row], for: .normal)
pickerView.isHidden = true
}

You can have two arrays to populate the picker like this
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int{
if numb == 1
{
return firstArray.count
}
else
return secondArray.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if numb == 1
{
return firstArr[row]
}
else
{
return secondArr[row]
}
}

Whenever you have to change the data source for datepicker, make sure after that you are calling method
picker.reloadAllComponents()
Take flag and use appropriate data source.

let say you added 2 PickerView to your View
- set the 1st pickerĀ“s tag as 1 & 2 for the 2nd picker under the Attributes Inspector
- CTRL + drag from each picker to the top yellow View Controller icon and choose dataSource.Repeate the same choosing delegate
- repeate the above for the other picker too
- add pickerview & pickerviewdelegation to your ViewController class:
class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
in your ViewController class, create empty arrays for the pickers:
var picker1Options = []
var picker2Options = []
on viewDidLoad() method, populate the arrays with your content:
picker1Options = ["p1 1","p1 2","p1 3","p1 4","p1 5"]
picker2Options = ["p2 1","p2 2","p2 3","p2 4","p2 5"]
implement the delegate & pickerview methods:
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (pickerView.tag == 1){
return picker1Options.count
}else{
return picker2Options.count
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if (pickerView.tag == 1){
return "\(picker1Options[row])"
}else{
return "\(picker2Options[row])"
}
}
Hope this will help.

let arrAny : [String] = [String]()
button action:
#IBAction func btn2Pressed(_ sender: UIButton) {
arrAny = ["Lion1", "Dog1", "Monkey1", "Cat1", "Bat1"]
if pickerView.isHidden {
pickerView.isHidden = false
}
}
#IBAction func btn1Pressed(_ sender: UIButton) {
arrAny = ["Lion", "Dog", "Monkey", "Cat", "Bat"]
if pickerView.isHidden {
pickerView.isHidden = false
}
}
pickerView delegate:
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return arrAny.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return arrAny[row]
}

Related

Swift 4.2 - PickerView not showing Content

this code makes me really mad. I already read thousands of tutorials and stack overflow comments....
Please help me. The Picker just contains a blank grey screen.
Code here:
GenderPickerModel.swift
import UIKit
class GenderPickerModel: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
let genderPickerData: [String] = ["male", "female"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1;
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return genderPickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return genderPickerData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
}
and used in a Controller:
#IBOutlet weak var gender: UITextField!
private var genderPickerView: UIPickerView?
override func viewDidLoad() {
super.viewDidLoad()
loadProfile()
prepareView()
}
func prepareView() {
genderPickerView = UIPickerView.init()
let gpModel = GenderPickerModel()
genderPickerView?.delegate = gpModel
genderPickerView?.dataSource = gpModel
gender.inputView = genderPickerView;
genderPickerView?.selectRow(0, inComponent: 0, animated: true)
genderPickerView?.reloadAllComponents()
}
First, you do not need to do the separate array of gender in pickerview class and you don't need to create the instance of pickerview.
From this, you can see your datasource in your custompickerview
/**
Controller code where you can create instantiate picker assign data
*/
class ViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
let genderPickerData : [String] = ["male", "female"]
override func viewDidLoad() {
super.viewDidLoad()
prepareView()
}
func prepareView() {
genderPickerView = UIPickerView()
let gpModel = GenderPickerModel()
gpModel.data = genderPickerData
gpModel.dataSource = gpModel
gpModel.delegate = gpModel
textField.inputView = gpModel
}
}
/**
Custom pickerview class where you can handle data
*/
import UIKit
class GenderPickerModel: UIPickerView, UIPickerViewDataSource, UIPickerViewDelegate {
var data = [String]()
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return data.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return data[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
}

Problem on displaying UIPickerView value on TextEditor swift

I'm having a problem displaying a value selected from a UIPickerView on a UITextField. I added all required functions to make it work but the textfield doesn't get updated.
Here is the ViewController.swift code
#IBOutlet weak var requestDestination: UITextField!
var itemSelected : String?
var pickerData = ["Bollate" , "Baranzate" , "Garbagnate" , "Novate Milanese" , "Paderno Dugnano" , "Certosa"]
override func viewDidLoad() {
super.viewDidLoad()
let thePicker = UIPickerView()
thePicker.delegate = self
thePicker.dataSource = self
requestDestination.inputView = thePicker
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView( _ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
private func pickerView( pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
itemSelected = pickerData[row]
requestDestination.text = itemSelected
}
#objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
requestDestination.resignFirstResponder()
}
I attached a screenshot where i show the first TextEdit that doesn't get the value from PickerView.
You have the wrong didSelectRow signature so it is never called. You missed the _. Let Xcode complete the methods for you instead of trying to type them yourself.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

My selector lines are only displaying one line in my Pickers. I'd like them to be like how the date picker is

For some reason I can't seem to get both selector lines in my pickers to show. They only seem to show one but the date picker is fine.
class HomeViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var linePicker: UIPickerView!
#IBOutlet weak var skuPicker: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
linePicker.delegate = self
linePicker.dataSource = self
skuPicker.delegate = self
skuPicker.dataSource = self
//passed over from previous view
var plantInfo = plantInformation
let totalNumberOfLines = plantInfo!["lines"].count
//populated the data
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if (pickerView.isEqual(linePicker)){
return lineInfo.count
} else {
return skusForPickerLine.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView.isEqual(linePicker) {
return lineInfo[row].lineNumber
} else {
return skusForPickerLine[row].sku_value
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let selectedValue = linePicker.selectedRow(inComponent: 0)
skusForPickerLine = lineInfo[selectedValue].skuInfo
skuPicker.reloadComponent(0)
}
func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
// height of picker is 50
return CGFloat(50)
}
}

Invalid redeclaration of 'numberOfComponents(in:)' error

Here's my code. I would say the steps I have taken, but they just don't make sense and I'd get made fun of, I am very new to Swift and Xcode. But how do I declare a group of components? I thought I spaced them enough, I have honestly searched for guides, but no one really focuses on dropdowns and variables within the dropdowns.
import UIKit
class SecondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var backBTN: UIButton!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var labelTwo: UILabel!
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var pickerviewTwo: UIPickerView!
var pickerData = ["X", "Y"]
var pickerdataTwo = ["R","D","C"]
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
pickerviewTwo.delegate = self
pickerviewTwo.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
label.text = pickerData[row]
}
func numberOfComponents(in pickerviewTwo: UIPickerView) -> Int {
return 1
}
func pickerviewTwo(_ pickerviewTwo: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerdataTwo.count
}
func pickerviewTwo(_ pickerviewTwo: UIPickerView, titleForRow row: Int, forComponent
component: Int) -> String? {
return pickerdataTwo[row]
}
func pickerviewTwo(_ pickerviewTwo: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
labelTwo.text = pickerdataTwo[row]
}
}
Your picker view code is wrong. First, I would recommend changing the names of them from pickerView and pickerViewTwo to something more descriptive.
The required functions for picker view can't be used multiple times, thus you are getting the error. The proper way to do it is:
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent
component: Int) -> String? {
//After renaming the first pickerView to topPickerView
if pickerView == topPickerView {
return pickerData[row]
}
else {
return pickerDataTwo[row]
}
}
There should be an if-else in each of the required functions, with the if statement saying that if pickerView == oneOfThePickerViewsName, with the if else statement. Whats happening is when the pickers are being set up, it checks which picker it is and uses the code for that.
Here is how the rest should be formatted:
//pickerView has been renamed to topPickerView
func numberOfComponents(in pickerView: UIPickerView) -> Int {
//You wouldn't need to do this here as its the same for both of them.
//
if pickerView == topPickerView
{
return 1
}
else
{
return 1
}
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == topPickerView
{
return pickerData.count
}
else
{
return pickerdataTwo.count
// should actually be formatted pickerDataTwo because of camelCase.
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent
component: Int) -> String? {
if pickerView == topPickerView
{
return pickerData[row]
}
else
{
return pickerdataTwo[row]
// should actually be formatted pickerDataTwo because of camelCase.
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent
component: Int) {
if pickerView == topPickerView
{
label.text = pickerData[row]
}
else
{
labelTwo.text = pickerdataTwo[row]
// should actually be formatted pickerDataTwo because of camelCase.
}
}

How to set title for row in PickerView in Swift 3?

I need to give title for rows according to array but I don't know how to do this. I'm new to iOS.
class ViewController: UIViewController , UIPickerViewDelegate, UIPickerViewDataSource{
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var label: UILabel!
var names: Array<String>?
var department: Array<String>?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
names = ["Vineeta", "Shubham" ,"Anand", "Vivek", "Akshay", "Harshit", "Vikas", "Prasoon", "Sunil"]
department = ["iOS","Angular", ".Net", "iOS","iOS", ".Net", "Android","Android", "Angular"]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 9
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
[names o]
}
}
}
don't forget UIPickerViewDelegate,UIPickerViewDataSource
#IBOutlet weak var picker: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
pickerData = ["X","Y"]
picker.delegate = self
picker.dataSource = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let selectedText = pickerData[row]
}
Use this code -
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
{
if component == 0
{
return names?.count
}
else
{
return department?.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
if component == 0
{
return names?[row]
}
else
{
return department?[row]
}
}

Resources