Getting values for two labels from single UIPicker - ios

Trying to fill two labels using single UIPicker. It has one column, two labels which have two buttons at the end of each label. On clicking which the UIPicker view is shown
#IBOutlet weak var userLoc1: UILabel!
#IBOutlet weak var userLoc2: UILabel!
let location = ["location1", "Location2", "Location3",
"Location4", "Location5", "Location6", "Location7"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
var countRow:Int = 0
if pickerView == LocationPickerView{
countRow = self.location.count
}
return countRow
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == LocationPickerView
{
let titleLocation = location[row]
return titleLocation
}
return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == LocationPickerView
{
selectedLocation1 = self.location[row]
self.userLoc1.text = self.location[row]
self.LocationPickerView.isHidden = true
//anything that can be done here that can assign different values to
//two label using the same UIPicker
}
Any guide to resolve the matter is greatly appreciated

Just add an extra column to your picker view and then add a second array to fill that new column.
It's all the same methods used to initialise the pickerview just with a bit of added logic.
let location1 = ["location1", "Location2", "Location3",
"Location4", "Location5", "Location6", "Location7"]
let location2 = ["location8", "Location9", "Location10",
"Location11", "Location12", "Location13", "Location14"]
// Set number of columns in your picker view
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
// Set number of rows of each column to length of arrays
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch component {
case 0:
return self.location1
case 1:
return self.location2
default: break
}
}
// Set content of rows in each column
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0:
return self.location1[row]
case 1:
return self.location2[row]
default: break
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == LocationPickerView
{
switch component {
case 0:
selectedLocation1 = self.location1[row]
self.userLoc1.text = self.location1[row]
case 1:
selectedLocation2 = self.location2[row]
self.userLoc2.text = self.location2[row]
default: break
}
self.LocationPickerView.isHidden = true
}

Related

UIPickerView get selected value without datasource

What would be the best way to get the value from a PickerView without having a datasource? So i can not read values from i.e. an array.
Current values are just row numbers, that i need to read after user is done with picking.
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return 300
} else {
return 10
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return "\(row)."
} else {
return "\(row)"
}
}
You can use pickerView.selectedRow(inComponent:)
let firstValue = pickerView.selectedRow(inComponent: 0)
let secondValue = pickerView.selectedRow(inComponent: 1)
Both will just be an Int value representing the currently selected row index in it's respective component. And since your values are starting from 0, you can use the values directly.
You simply add this func:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(row)
}
Just take care that row starets at 0

uipickerview index out if range

I'm trying to learn to code Swift and recently I faced a bug which is so embarrassing.
I have 2 textfield which both are connected to a picker view.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if EntCity.isEditing
{
return MainCities[row].name
}
return MainJ[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if EntState.isFirstResponder
{
EntState.text = MainJ[row].name
Global_Addresses.global_address.cityID_fromState = MainJ[row].id
GetCities()
}
if EntCity.isEditing
{
if (EntState.text?.isEmpty)!
{
DispatchQueue.main.async {
self.DisplayMessage(UserMessage: "ابتدا استان را انتخاب کنید")
}
}
else
{
EntCity.text = MainCities[row].name
Global_Addresses.global_address.smallCityID = MainCities[row].id
}
}
EntState.text = MainJ[row].name
Global_Addresses.global_address.cityID_fromState = MainJ[row].id
GetCities()
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return MainCities.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return MainCities[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
EntCity.text = MainCities[row].name
Global_Addresses.global_address.smallCityID = MainCities[row].id
print("?????????????????????")
print(Global_Addresses.global_address.smallCityID)
}
}
the code works fine and both textfield can show the data in the picker view to choose. these textfield are connected, it means that
you have to choose one of the rows in textfield number 1 to get the data for textfield number 2 . when i choose the first data , and select the second textfield to choose the second one , it works fine untill i choose of those data which their row number is bigger than the first textfield
and as you can see i have declared that if it select first or second textfield to return different number for row!

How to connect pickerviews and labels in iOS?

I have two pickerView and two Label on my ViewController.
The question is how I could connect labels to pickerView's data array (string type) and show in labels chosen pickerView cell?
#IBOutlet weak var valuetype1: UILabel!
var pickerData: [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.picker1.delegate = self
self.picker1.dataSource = self
self.picker2.delegate = self
self.picker2.dataSource = self
pickerData = ["Годы", "Месяцы", "Недели", "Дни", "Часы", "Минуты"]
}
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) {
valuetype1.text = pickerData[row]
valuetype2.text = pickerData[row]
}
How could you see I connected labels (valuetype(1..2)) to pickerData but it always show in both labels one String. I need to show in first label String chosen in pickerView1 and another string in second label, chosen in pickerView2.
UIPickerViewDelegate has a method called pickerView(_:didSelectRow:inComponent:). Add this method to your VC class. This method gets called whenever the user selects a row.
Your implementation should look somewhat similar to this.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
valuetype1.text = pickerData[row]
}
For more information refer to the apple docs: https://developer.apple.com/documentation/uikit/uipickerviewdelegate/1614371-pickerview
EDIT:
When you are using the same controller as a delegate for multiple UIPickerViews, then you can check which picker view triggered the method call simply by comparing the pickerView argument on the pickerView(_:didSelectRow:inComponent:) method.
Try this:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == picker1 {
valuetype1.text = pickerData[row]
} else if pickerView == picker2 {
valuetype2.text = pickerData[row]
}
}

Update UITableViewCell

I've got a problem. I have this tableview and this pickerView
and this is the pickerView functions of the viewcontroller:
let gender = ["M","F"]
#IBOutlet weak var dataTableView: UITableView!
//pickerFuncs
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gender[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return gender.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
print(gender[row])
}
How to modify the "m" in the cell with the selection of the uipicker? thanks everybody!
Create a variable
var currentGender = "M"
Set your TableViewCell with currentGender like
cell.gender = currentGender
When you select a row in UIPickerView,
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
currentGender = gender[row]
// Then reload your TableView row
let indexPath = IndexPath(item: rowNumber, section: 0)
tableView.reloadRows(at: [indexPath], with: .top)
}
I'm assuming you want to have your M and F appear inside your pickerView. To do this you have to create a reference. This can be done through an IBOutlet or you can do it programmatically like so: let pickerView = UIPickerView(). On a side note, I am also assuming you are only using one pickerView in the View Controller. If you are using multiple, set each of the pickerViews a tag. This can be done in the interface builder and programatically like so: pickerView.tag = 1. Then change your pickerView functions based on those tags.
Create a variable.
var gender = "M"
Initialise again your gender variable. In this delegate method.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
gender = gender[row]
// Then reload your TableView row
table view.reloadData()
}
Add these lines to your cellforrow_atIndexPath.
Cell.genderIdicatorLbl.text = gender
Note: genderIndicatorLbl is IBOutlet for your gender indicator Label

Populate UIPickerView with items from class

I have the following class:
class JobItem {
var ItemID:String = String()
var Qty:Int = Int()
var Item:String = String()
}
I also have a collection of items in this class like so:
var jobitems: [JobItem] = []
I would like to populate my pickerview with just the Item part from each instance of the class in the array and I'm not sure how. I successfully filled it with data from a dummy array I created so it's working OK, just need that data in.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return jobitems.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return as? String
}
Try this in your titleForRow, you just need to return the correct Item string with the correct row that can mapped to index of your array:
return jobitems[row].Item
Just takeout element from array to your instance class & populate what you wants,
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String {
var titleFoRow: String? = nil
var classObject: ModelClass? = nil
classObject = self.arrayCountryList[row]
self.titleFoRow = classObject.instanceVarName
return self.titleFoRow
}

Resources