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:
Related
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
What I'm trying to do is have a button that will pull the information from UIPickerviewer that will then add that to an array but when the program runs and you hit the button it crashes. Quite new to programming in swift... Would like a better explanation.
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var PickerView: UIPickerView!
#IBOutlet var list: [UILabel]!
#IBAction func add(_ sender: UIButton) {
var shift = true
}
#IBOutlet weak var label: UILabel!
var deviceList = [""]
var shift = false
override func viewDidLoad() {
super.viewDidLoad()
label.text = "Device List"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
let devices = ["Mobile Phone","Microwave","Heater","Fridge","Router","Drill"]
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return devices[row]
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return devices.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
label.text = devices[row]
if(shift == true){
deviceList.append(label.text!)
print(deviceList)
shift = false
}
}
}
If you're getting a crash when you tap on your button I assume there is some conflicting assignments with the IBOutlet events referencing. The reason being is because your add(_:) action method isn't doing anything but creating a new boolean property called shift, and even though it's the same name as the class property shift (self.shift), that actually shouldn't cause a crash. Sometimes in interface builder you can have an outlet that you accidentally assigned more than one event, and that has usually caused a crash in my experience if you deleted one of the events in your code. For example: say you created a event for your button (like add(_:)), and then forgot and accidentally created a second one. You then realized your mistake and deleted the code for the second event, but didn't know you had to remove the event outlet. Interface builder will allow you to make this mistake, but will cause the app to crash when you tap the button, because it's trying to call an event that doesn't exist anymore.
If you want to check if you have any unnecessary event assignments through IB, control+click on the button in your documents outline on the left side of the screen using Interface Builder.
You'll see the referencing outlets listed under the "Referencing Outlets" header. You can remove any unnecessary ones by clicking the little "X" to the top left. You can also tell if the outlet is actually connected, by checking if it has a little filled circle to the right (this means it's connected). Here is an example, in this case I created an event call to a method called tryAgain: which I then removed. It causes a crash when I tap the button.
If I click the "X" button and remove the tryAgain: event. The app will work when the button is clicked.
I'm not certain this is your issue, but based on what you've shared it sounds likely to me. Hope this helps. I would recommend actually executing some code in your add(_:) method, however.
Nothing about the IBAction you posted should be causing a crash. You do need to get rid of the word "var" in the body of the function so that it changes the state of your instance variable rather than setting a local variable that never does anything, but that won't cause a crash.
That said, your "label" outlet is declared as an implicitly unwrapped optional, which is normal for outlets:
#IBOutlet weak var label: UILabel!
If the outlet is not connected to anything, though, then any time you try to read from or write to the label outlet or a property of the label, you'll crash if label is nil.
Check to see if you outlet is hooked up correctly. If it's not, then I would expect you to crash when you operate your picker. (Not when you click the add button.)
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.
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.