I would like to know if i could get the selected String of a PickerView because when using the method func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) i only know the row selected and what i am using is if i know the row i know the position on the array i used to load the PickerViews but i wanted to do this pickerView.text to do something like this
if (pickerView.text == "hello"){
doSomething(pickerView.text);
}
Because now i have to do much more code lines to do something like this
Sorry i forget to mention, i have 3 PickerView and to know the String is in the third picker view i have to see what row is selected in each one
i only know the row selected and what i am using is if i know the row i know the position on the array
And that's the answer. Don't fight the framework; use it. The framework uses Model-View-Controller. The UIPickerView is view; it has no data. You have the data, and given the row, you can fetch it from the model.
extension UIPickerView {
func selectedTitleForComponent(component: Int) -> String? {
let row = selectedRowInComponent(component)
return dataSource.pickerView(pickerView, titleForRow:row, forComponent:component)
}
}
Then:
if pickerView.selectedTitleForComponent(0) == "hello" {
...
}
Related
I have 2 UIPickerViews in an ios program which I am running on an iPad simulator.
They have one component in each.
I find the relevant picker view by using a switch on the tag. The two single component views need to be changed by adding or deleting components.
This is easy enough in the data source with
pickerData.append(textInput)
pickerData.sort()
pickerData.reloadAllComponents
and
pickerData.remove(at: lastDataSelected)
picker.reloadAllComponents()
where lastDataSelected is the row integer.
This works to change the data source but not entirely when transferred to the UIPickerViews.
The UIPickerView display is not updated until I scroll the view. To be more precise, the item selected is correct but the text label is not updated. After scrolling the data labels are all showing correctly.
I have tried to programatically scroll from one end to the other but this does not help.
So how can I tell the program to update the view without the user scrolling it?
picker.reloadInputViews() does not help.
Apart from this the number of items (rows) isn't changed to reflect the changes in the picker data so the last item falls off the list when adding a new one.
So the second question is how to get the UIPickerView functions to update the number of rows?
I haven't been able to find any examples of dynamically updated picker views so hope someone can help or point me in the right direction.
The remaining code is fairly standard I believe but I'm obviously missing something in the update process.
override func viewDidLoad() {
super.viewDidLoad()
flvPicker = UIPickerView()
flvPicker.delegate = self
flvPicker.dataSource = self
flvPicker.tag = 0
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
switch pickerView.tag {
case 0:
return 1
case 1:
etc...
}
}
var numberOfRowsInComponent = 0
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch pickerView.tag {
case 0:
return flvPickerData.count
case 1:
etc...
}
}
func pickerView(_
pickerView: UIPickerView,
titleForRow row: Int, forComponent component: Int) -> String? {
switch pickerView.tag {
case 0:
return flvPickerData[row]
case 1:
etc...
}
}
func pickerView( _ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch pickerView.tag {
case 0:
flavourSelected = flvPickerData[row]
lastFlavourSelected = row
case 1: etc...
}
}
I think the question is really how to get the UIPickerView to update correctly after making changes to it's data source and therefore row count.
You can use reloadComponent(_:) method from UIPickerView.
A little late to the party, but if you want to update a picker view, there's also the method selectRow. This also has the benefit of an animation property, so you can animate any updates.
Example:
for (index, day) in weeklyOptions[0].enumerated() {
if scheduledTime.contains(day) {
weeklyDatePicker.selectRow(index, inComponent: 0, animated: true)
}
}
In my app, I have a UITextField and UIPickerView acting as dropdown, when user clicks on text field, he has to select his gender (Male or Female. I just want to read the value / string which user has selected in text field.Could some one please help me here
#IBAction func textChange(_ sender: UITextField) {
if userGenderTextField (Something has to here, Not sure what exactly)== "Male" {
print("Hello Sir")
} else {
print("Hello Madam")
}
}
You just have to use the .text method of UITextField
#IBAction func textChange(_ sender: UITextField) {
if sender.text == "Male" {
print("Hello Sir")
} else {
print("Hello Madam")
}
}
If you have several text fields connected to the same IBAction, you also need to check which text field called the function.
This sounds like a round-a-bout way of doing it.
Presumably at some point you're detecting which item in the UIPickerView the user selects and setting the text on the UITextField?
If so, why not store this value as a property. Then you always have access to it.
It doesn't seem like the best idea to have to inspect the text value of a UITextField when you want to know the state of play.
First of all, create a uIPickerView programmatically and set its dataSource and delegate properties to some objects that conform to the UIPickerViewDataSource and UIPickerViewDelegate respectively. The best approach is to have the object that controls the UITextField and UIPickerView conform to both these to protocols since you will be needing direct access to your textField and pickerView.
UIPickerViewDataSource is to control the data that is displayed in the picker.
UIPickerViewDelegate is to receive events that happen on the picker (e.g when the user selects an option).
Once you have your pickerView ready and set up you have your pickerView as the inputView of your textField
textField.inputView = pickerView
this way, when someone clicks on the textField, instead of presented the keyboard, you will be presented with you pickerView complete with your data.
On UIPickerViewDelegate there is a function called:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
that gets called everytime you select an option on the pickerView.
Inside that function you can set the text of your textField and have it accessible elsewhere:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
textField.text = yourData[component][row]
}
In if statement you put textfieldname.text== male print male else female
I have 2 pickers, the user sets their desired int on them and then saves the object to core data.
Later when they want to edit the object they reload its data into the editor.
I am having an issue where the pickers cannot pull the int back from core data and default themselves to this value, they always default to '0'
Is there a method to make the pickers default to the desired int stored in the object they are editing?
I have the following delegate methods in place:
repsPicker.dataSource = self
repsPicker.delegate = self
setsPicker.dataSource = self
setsPicker.delegate = self
I then try to take the properties from the object and apply them to the pickers, however im using NUMBER? in place of where id assume i need ot put code to access the default values of the pickers, here is where im stuck...
setsPicker.selectedRow(inComponent: Int(userExercise.sets))
repsPicker.selectedRow(inComponent: Int(userExercise.reps))
The data type of userExercise.sets or .reps is Int64 if that helps?
Many thanks for your time and assistance
edit-
here is the component override
func numberOfComponents(in pickerView: UIPickerView) -> Int {
if pickerView == repsPicker {
return 1
} else if pickerView == setsPicker {
return 1
}
return 1
}
you should use selectRow func not selectedRow
func selectRow(_ row: Int,
inComponent component: Int,
animated animated: Bool)
so, it should be
setsPicker.selectRow(Int(userExercise.sets), inComponent :0,animated:false)
repsPicker.selectRow(Int(userExercise.reps), inComponent :0,animated:false)
I'm reading a Swift OOP book and I understand the idea of instance methods having arguments which will be used within the function. What is unclear is while following online tutorials for UIPickerViews and UITableViews, there are methods that have UIPickerView or UITableView objects as parameters but aren't used in the function.
For example:
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
// Return the number of rows of data
return gamesList.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return gamesList[row].name
}
The first parameter pickerView which takes a UIPickerView object isn't used within these functions. I'm wondering why have them as parameters in the method's signature but these objects are rarely used in tutorials? Or am I thinking about this incorrectly?
Thank you in advance for any help to get a better understanding.
The first object from all the Delegate and Datasource methods that you are talking about is not unused object, it will hold the reference of the current UIPickerView, So it will used if you have multiple UIPickerView in the same ViewController. Same thing goes for all the others control like UITableView, UICollectionView etc.
For eg if you have 2 UIPickerView in the same Controller then you can fill the UIPickerView by comparing it in the UIPickerView methods.
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == firstPickerView {
return gamesList1.count
}
//else return for second pickerView
return gamesList2.count
}
So you need to compare the pickerView reference in all the methods of UIPickerView and fill or access the data according to it.
I've a many textfield and a pickerView with toolBar and it has a done button. My issue is I can't select the first row from the picker. While I have debugged in the didSelectRow but it won't run inside it. So please where would be my issue?
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
var value = currentPickerArray[row]
textFieldOutletArray[currentTag].text = value
}
Just replace didSelect method in your sample code like as bellowed. it will working fine.
#IBAction func doneBtn(sender: AnyObject) {
var row = pickerView.selectedRowInComponent(0);
NSLog("value L %d", row)
pickerView(pickerView, didSelectRow: row, inComponent:0)
}
Hope this help you.
In the titleForRow function add this line of code. It shows first row selected:
textField.text = pickerArray.objectAtIndex(row).objectForKey("Name") as? String