Drop-down style UIPickerView? - ios

I was wondering how to get a UIPickerView to slide up from the bottom of the screen after tapping on a drop-down style button. Like in the image below:
I've run into this type of picker views a lot in the apps that I use regularly, so honestly I was expecting to easily find this picker view by setting the UIPickerView's style property, or something like that. Is this even a UIPickerView or do I have to create this kind of view manually?

One way of doing this is to have a normal UITextField and then assign a UIPickerView as the inputView of that textfield. That way, instead of a keyboard appearing when you tap your textfield, you get your pickerview.
Example
First declare a normal UIPickerView instance:
let yourPicker = UIPickerView()
and an outlet to a UITextField:
#IBOutlet weak var yourTextField: UITextField!
In your viewDidLoad you tie the elements together
yourPicker.delegate = self
yourPicker.dataSource = self
yourTextField.inputView = yourPicker
And then you need to implement the required methods of UIPickerViewDelegate and UIPickerViewDataSource
Finally. In pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) you update the value of your textfield:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
yourTextField.text = yourDataArrayUsedInThePicker[row]
}
Read more
Description of inputView
https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/InputViews/InputViews.html
A way better explaination than mine:
Show UIPickerView text field is selected, then hide after selected
Hope that helps you.

Related

How can I get the selected value in the real-time, when I'm scrolling the UIPickerView

For example, in this image, when I'm scrolling the UIPickerView to 2012 9 28, what I want is that the text of the black label will change into 2012 9 28 at the same time without pressing any buttons like the Done button
I’m using UIPickerView, I can get the selected data before, I can also put the data into label by clicking a Done button, but I cannot put the data into the label when I’m scrolling.
and In a general situation,
My question is that when I Scroll the UIPickerView, how can I get the data which is selected in real time
could anyone help me ? ObjectiveC solution is OK, Swift solution is better for me, Thank you so much
It is unclear if you are using a UIPickerView or a UIDatePicker.
For UIPickerView you need to implement the UIPickerViewDelegate. Make sure that delegate is added to your ViewController declaration and make sure in Storyboard to connect the delegate of the UIPickerView control to your view controller. Then implement this function:
func pickerView(_ pickerView: UIPickerView,
didSelectRow row: Int,
inComponent component: Int) {
}
For UIDatePicker you need to connect the action of the UIDatePicker in Storyboard to an #IBAction function in your view controller or else connect it in code using the addTarget function:
myDatePicker.addTarget(self, action: #selector(self.respondToPicker, for: .valueChanged),
Let me suppose that you are using UIDatePicker, in that you can control the action using UIControlEventValueChanged
Like,
datePickerView?.addTarget(self, action: #selector(self.valueChanged(_:)), for: UIControlEvents.valueChanged)
the valueChanged() will be,
func valueChanged(_ datePicker: UIDatePicker) {
let selectedDate = datePicker.date as NSDate
print(selectedDate)
}
and if you are using UIPickerview then,
titleForRow: will gave you scrolling value
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String?
{
print("your value")
}
and didSelectRow: will give you selected value
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
print("your value")
}

Reading value of UITextField Swift 3

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

Get UITextField from UIPickerView when using it as input view

Is there a possibility to get UITextField from UIPickerView? I set my UIPickerView as inputView for text filed. I have few text fields on the screen and I want to simple get current text field that shown picker view.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
// something like let textField = pickerView.requestedTextField
}
Is there any way to do it?
If you have multiple textField that show pickerView then create one more instance of textField in your viewController like this and use this object inside textFieldDidBeginEditing and assign the reference of that textField to that tempTextField.
var selectedTextField: UITextField = UITextField()
func textFieldDidBeginEditing(textField: UITextField!) {
self.selectedTextField = textField
}
Now in didSelectRow method of PickerView use this textField o know the current editing field.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if self.selectedTextField == countryField {
//Set text for countryField
}
else self.selectedTextField == stateField {
//Set text for stateField
}
}
Note: For example I have used countryField and stateField you can use textField for that you want to set text.
Set same tag to your pickerview and textfield both.
now you can get your tag in didSelectRow like,
let myTag = pickerView.tag
and then from myTag you can get your textfield something like,
let myTextField = self.view.viewWithTag(myTag) as! UITextField
As user Lion rightly pointed out in his answer, you can get the corresponding UITextField by giving both the pickerView and textField a tag. However, the issue with giving them the same tag is that viewWithTag may return the UIPickerView itself, depending on the order of the subviews.
As this is unreliable, a better solution would be to give the UITextField the negative of the tag given to the UIPickerView (eg. 1 and -1). To get the UITextView, you would do something like this in your method, once you have assigned your picker views and text views opposite tags:
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let textField = view.viewWithTag(-pickerView.tag) as! UITextField
//Use textField
}

Send button, which opens UIPickerView to UIPickerView's selectRow function

I have two buttons, which opens one UIPickerView
#IBOutlet weak var convertFromButton: UIButton!
#IBOutlet weak var convertToButton: UIButton!
I need picker's selectRow function to know, which button user press to open it and to change title of this button. So, I need function like this, but I don't know how to send button to this function.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int, button: UIButton) {
button.setTitle(converter.convertTypes[row], forState: UIControlState.Normal)
typePicker.hidden = true;
}
Or do I need separate picker for each button?
You can use additional variable to store the latest sender button which was used to open a picker and check its value in the pickerView:didSelectRow:

Programmatically implementing a UIPickerView when user taps UITextfield

I am currently working on a small project and i have a viewController that has 4 textFields which 3 work ok. They take String objects. However, the 4th textField is supposed to bring up a UIPickerView with 4 selectable items.
So far this is what i have in my controller that implements this:
#IBOutlet var pickerTextfield: UITextField!
#IBOutlet var itemPicker: UIPickerView! = UIPickerView()
The pickerTextfield is the UITextField object that is the 4th field.
The itemPicker is an unlinked UIPickerView that i want to create programatically.
Right below these properties, i have an array of items for the UIPickerView object:
var seasonalItems = ["Spring", "Summer", "Fall", "Winter"]
In my viewDidLoad method i have this as follow:
itemPicker.hidden = true;
pickerTextfield.text = seasonalItems[0]
pickerTextfield.delegate = self
And the rest of the implementation:
// Below these lines is the implementation of the Picker
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int{
return 1
}
// returns the # of rows in each component..
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int{
return seasonalItems.count
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
return seasonalItems[row]
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int)
{
pickerTextfield.text = seasonalItems[row]
itemPicker.hidden = true;
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
itemPicker.hidden = false
return false
}
So the end result from this is when i tap the pickerTextfield object in the app, it shows the first item of the array (Spring) but in text within the UITextField object but it does not show the UIPickerView object with the other selectable items where i could select one and then hide it when selected.
My question is, where or what am i doing wrong here? i been trying to figure this out on my own but i do not seem to get good clear examples with Swift and storyboards. I much rather not drag a UIPickerView in the storyboard but rather the way i attempted to implement. Thanks
You can give UIPickerView as inputView for your TextField in which you want to show picker view.
You also do not need to initially hide picker view in this case.
pickerTextfield.inputView = itemPicker
When you use UIPickerView as inputView of any UITextField then when you tap on the TextField instead of default keypad PickerView will show.

Resources