I have a picker view that needs to be presented when UIButton is pressed. The text of the UIButton will change to the text of selected row. But how do I initiate the picker view for a button?
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
override func viewDidLoad() {
super.viewDidLoad()
picker.delegate = self
picker.dataSource = self
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return CountryData.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
CountryButton.setTitle(CountryData[row], for: .normal)
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return CountryData[row]
}
#IBAction func Country(_ sender: AnyObject) {
CountryButton.inputView == picker
}
This won't work
Note: when you set the action method, be sure to set the sender to the type of control that's invoking the action, the UIButton or the UIPickerView or whatever. Don't leave it as AnyObject.
It's not completely clear to me what you're trying to do. You say that the picker view needs to change when you press a button, then you say that the text of the button needs to change to the row selected in the picker view.
Are you trying to get the text of the button to change when you select something in the picker view? Or are you trying to instantiate a new picker view when you press the button?
If you're trying to change the text of the button when you select a row in the picker view, then you want to add an onChanged() action method for the picker view and change the button's text in that method.
#IBAction func pickerChanged(_ sender: UIPickerView) {
button.setTitle("New text", for: UIControlState)
}
An easy way to present a new picker view when a button is pressed is to put the picker view in a stack view and set its hide property. Then the button's onPress() method can unhide the picker view in the stack view.
#IBAction func onPress(_ sender: UIButton) {
if weWannaShowthePicker {
pickerStack.arrangedSubviews[pickerPosition].isHidden = false
} else { // hide it
pickerStack.arrangedSubviews[pickerPosition].isHidden = true
}
}
Related
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")
}
In my picker view I want the default row to be zero. This row has a value of 1. I want to be able to touch nothing on the view contoller except a button. I know there are similar questions but they did not work for me.
override func viewWillAppear(_ animated: Bool) {
self.pickerView.delegate = self
self.pickerView.dataSource = self
self.pickerView.selectRow(0, inComponent: 0, animated: true)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return String(numbers[row])
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return numbers.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
therow = pickerView.selectedRow(inComponent: 0) + 1
}
then
#IBAction func submitTapped(_ sender: Any) {
Print (therow)
}
When I tap submit and print the value at row 0 it is 0, but if I wiggle the picker view and put it back on row 0 then it prints 1. I need to be able to touch nothing on the picker view and have it return the proper value of the default row.
You should use the row that the pickerview delegate method gives you , so you should modify your code as follows:
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
therow = numbers[row]
//theRowIndex = row //this is the index of row that you selected
}
e.g if numbers array is numbers = [1, 2, 3, 4], when you click on first row above code will set therow to be 1 and if you click on second row, it will set therow to be 2 and so on.
if you want to use the code that you wrote then you can use as follows:
therow = numbers[pickerView.selectedRow(inComponent: 0)]
this will give you the number for selected row , but I think you dont need it inside the above method.
Now if you dont want to touch the picker then I think you need to do this:
#IBAction func submitTapped(_ sender: Any) {
therow = numbers[self.pickerView.selectedRow(inComponent: 0)]
print(therow)
}
Use this statement once you load your picker view with data.
yourPicker.selectRow(0, inComponent:0, animated:true)
You can change the default selected value by changing the first parameter of selectRow.
I think the reason why this happens is that didSelectRow is somehow not called if you selected the row programmatically. As per the docs:
Called by the picker view when the user selects a row in a component.
So you need to set your therow property programmatically after you call selectRow:
self.pickerView.selectRow(0, inComponent: 0, animated: true)
therow = 1 // <--- this line
I'm making a GPA calculator using swift and I've run into some problems. I created a picker view with all the letter grades (A to F). I've put 7 text fields (one for each course). I want the user to tap on a textfield and the pickerview should appear, and the grade selected would appear in the textfield. I've managed to do that for the first textfield but I dont know how to write the code that allows me to pick the grade for each textfield. I've tried different methods but I always end up changing the first textfield only.
Any help is appreciated :-)
Here is my code (gradeOne is a textfield for course 1, gradeTwo for course 2, etc.):
import UIKit
class GPA: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet var gradeOne: UITextField!
#IBOutlet var gradeTwo: UITextField!
//Grades array
var grades = ["A+/A (85-100)", "A- (80-84)", "B+ (77-79)", "B (73-76)", "B- (70-72)", "C+ (67-69)", "C (63-66)", "C- (60-62)", "D+ (57-59)", "D (53-56)", "D- (50-52)", "F (0-49)"]
//Grade 1 Picker
func numberOfComponentsInPickerView(gradePickerView: UIPickerView) -> Int {
return 1
}
func pickerView(gradePickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return grades.count
}
func pickerView(gradePickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return grades[row]
}
func pickerView(gradePickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
gradeOne.text = grades[row]
}
//Make keyboard disappear
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let gradePickerView = UIPickerView()
gradePickerView.delegate = self
gradeOne.inputView = gradePickerView
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
view.addGestureRecognizer(tap)
}
func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
}
You should set gradePickerView as the inputView for all your textfields
gradeTwo.inputView = gradePickerView
gradeThree.inputView = gradePickerView
// set for rest of textfields
and then in your pickerView:didSelectRow: method you need to set the text to the active text field at the time. I suggest setting the active textfield using UITextFieldDelegate
var activeField: UITextField?
override func viewDidLoad() {
// Set VC as textfield's delegate
gradeTwo.delegate = self
gradeThree.delegate = self
// Set for rest of textfields
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
activeField = textField
}
func pickerView(gradePickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
activeField.text = grades[row]
}
Use the delegate for UITextField to set all inputviews to pickerView. Make sure you set delegate for all textfields
let gradePickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
// set delegates for all textfields
gradePickerView.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
view.addGestureRecognizer(tap)
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
textField.inputView = gradePickerView
}
I think you want to tap on 7 textfiel. Each time the pickerView will show. You picker a cell in pickerView and the textfiel(that you just tap) will show your select? If it's true. You should do fowllow this step:
1: Add tag to each textFiel: yourtextFiel.view.tag = 0 (or 1,2,3,4,...)
2: When show pickerView: Add pickerView.tag = yourtextFiel.view.tag
3: in fucion pickerView didSelectRow : get your textFiel's tag will show your selected: let mytag = pickerView.tag.
Find your textFiel with "mytag" and change your text
Googluck
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.
I'm new in swift and programming. I have a UIPickerView and UIbutton(by default button is invisible ) in my storyBoard and i want to show myButton when I change row in a UIPickerView (PickerView.selectedRowInComponent(0) == 1) and when press MyButton do something. Here is my code: MyButton and PickerView.
How can i show myButton?
#IBAction func myButton(sender: UIButton) {
println("Button was clicked", sender)
//here i will do something
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if PIckerView.selectedRowInComponent(0) == 1 {
//how to set UIButton property visible, here ???
}
Try this:
myButton.hidden = false
To get access to your button in code you need to create an IBOutlet: In InterfaceBuilder ctrl-drag from the button to your class file and in the popup menu choose outlet. Give that outlet a descriptive name i.e. myButton. Also give your #IBAction a descriptive name, not myButton
So your class will look similar like this:
#IBOutlet weak var myButton: UIButton!
#IBAction func myButtonClick(sender: UIButton) {
println("Button was clicked", sender)
// here i will do something
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if PIckerView.selectedRowInComponent(0) == 1 {
myButton.hidden = false
}
}
And don't forget to assign your custom class in InterfaceBuilder accordingly.