UIPickerView get selected value without datasource - ios

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

Related

for loop in titleForRow in pickerView not working

I was creating a clock pickerView and used the following:
var countSec = Array(0...10)
var countMin = Array(0...59)
var countHour = Array(0...59)
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0{
for count in countSec {
return "\(count)"
}
}else{
for count in countMin{
return "\(count)"
}
}
return nil
}
But when I run, all the data was 0s.
Don't use loops in titleForRow. Just return the appropriate value for the requested row.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return "\(countSec[row])"
} else {
return "\(countMin[row])"
}
}

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!

UIPickerView depending on first component

So I have a UIPickerView with two components. The first one called "Cupboards", the second "Drawer". They have a one to many relationships in CoreData Cupboards <-->> Drawer. I would like that if I select a Cupboard, only the matching Drawers get displayed. I'm not sure how to get that working with the relationship.
That's what I have for showing the Cupboard:
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component==0){
return cupboards.count
}
xxxx
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if(component==0){
return cupboards[row].name
}
xxxx
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
}
}
Thank you in advance
Update:
Got it like that now, but I get no results.
var cupboardDrawers = [Drawer]()
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
let request: NSFetchRequest<Drawer> = Drawer.fetchRequest()
request.predicate = NSPredicate(format: "cupboard == %#", cupboards[row].name!)
do{
let result = try mgdContext.fetch(request)
cupboardDrawers = result
addEatDataPicker.reloadAllComponents()
}catch{
print(error.localizedDescription)
}
}
}
You need to create and update a cupboardDrawers array with the fetching results:
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component==0){
return cupboards.count
} else {
return cupboardDrawers.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if(component==0){
return cupboards[row].name
} else {
return cupboardDrawers[row].yourProperty
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component==0){
// you can add this part to a separate function and call it here
cupboardDrawers = []
let request = NSFetchRequest<Drawer>(entityName:”Drawer”)
request.predicate = YourPredicate with cupboards[row].name
do {
let items = context.fetch(request)
guard items.count > 0 else {
print(“no items found”)
return
}
cupboardDrawers = items
//reload your picker
} catch {
print(error)
}
}
}

Getting values for two labels from single UIPicker

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
}

Swift - how to concatenate didSelectRow selections from UIPickerView

I have a two column picker (Miles and Tenths)
Picker seems to work well, but I cannot seem to work out how to concatenate the selections from the two columns i.e. if user selects 23 from first column and 6 from second column, I want to create an answer of "23.6"
At the moment, either column selection overwrites the previous selection.
BTW: I don't think I can append two strings because what happens if user selects the 10ths first?
let resetPickerData = [Array(0...99), Array(0...9)]
// returns the number of 'columns' to display.
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int{
return 2
}
// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int{
return resetPickerData[component].count
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
return String(resetPickerData[component][row])
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
//var distance = ??
}
You'll need to keep track of the component selection separately like this then concant the strings:
var firstComponentString = ""
var secondCompoentString = ""
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
if component == 0 {
firstComponentString = String(resetPickerData[component][row])
}
else if component == 1 {
secondCompoentString = String(resetPickerData[component][row])
}
var displayString = "\(firstComponentString).\(secondCompoentString)"
}

Resources