I have 2 text fields in my storyboard. One for username, the other one to pick a date. However, I am trying to validate the if the user has a specific amount of characters in the username:
func addTargetToTextField() {
registerUserNameText.addTarget(self, action: #selector(textFieldDidChange), for: UIControl.Event.editingChanged)
}
and
#objc func textFieldDidChange() {
let isText = registerUserNameText.text?.count ?? 0 > 3
if isText { ... etc
I am trying to copy that methods on my date picker text field, but it is not working. Im not a Swift expert, but I think it is because the user picks a date and not writing something in the textfield.
How can I check if a date in the textfield was picked?
I changed the addTarget method of my DatePicker and not the TextField using .valueChanged and it is working now.
Related
Let's say that I have a UIDatePicker and the mode is set to .date.
I want the following behaviour:
For example, March has 30 days. If I scroll below the 30th day, I want the month to be automatically incremented to April and so on.
Is there a property that does just that? I couldn't find one.
Thanks.
I don't think there's any way to do what you want with a normal UIDatePicker. You could attach an action to the valueChanged event, but that doesn't get called until the date picker stops moving.
You could probably create a custom date picker using a standard UIPickerView. You could use the data source methods to figure out when the "wheels" are turned, call selectedRow(inComponent:) to figure out which values are selected for each wheel, and then call selectRow(_:inComponent:animated) to switch the month if the user scrolls the day past the end of the month.
How to advance other fields in datePicker automatically?
The best way to do this is using the Target-Action design pattern. Basically, when a user chooses a new date (action), the view (a target) does something.
Here's some code that changes the day value to 1 if it's set to 0:
override func viewDidLoad() {
...
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
datePicker.addTarget(self, action: #selector(doStuff(sender:)), for: UIControlEvents.valueChanged)
view.addSubview(datePicker)
...
}
#IBAction func doStuff(sender: UIDatePicker) {
let calendar = Calendar.current
let components = calendar.dateComponents([.day], from: sender.date)
if components.day == 0 {
// Using Calendar.current automatically takes care of Time Zones for us.
if let date = calendar.date(byAdding: .day, value: 1, to: sender.date) {
sender.setDate(date, animated: true)
}
}
}
Note: This example is in Swift 4.
No, there is no property that does this that I am aware of.
I have a UIViewController with several UITextFields. When tap one text field, it should present the barcode scanning view controller. Once the scanning is completed, my barcode scanning viewcontroller is disappearing (used "dismissViewcontroller") and the scanned value should entered into the text field I tapped. This is working fine. I have set the delegate for each text field like this.
[field addTarget:metrixUIViewControllerIn action:#selector(executeScriptOnTextFieldChange:) forControlEvents:UIControlEventEditingChanged];
The problem is this :
Lets say I have set an alert to display inside this executeScriptOnTextFieldChange method. Once I tapped on the 1st text field, then the barcode scanner comes. Once I scanned barcode scanner closes and set the value for the first text field and fire the alert.Thats ok. But then if scanned by tapping the 2nd textfield and the string will set to that textfield and fire the alert related to 2nd textfield also fire the alert related to first textfield as well. I want to stop happening this. Is there any way to disable the delegate for one textfield? This happens because I am refreshing the view in the viewDidAppear. But I have to do that as well. Please help me.
UIControlEventEditingChanged for a textField can fire at many different events that are not even directly related to that textField, but related inderectly.
For instance, when your ViewController is presenting the barcodeScanner it may trigger a "resignFirstResponder" event on the textField. Also when the 2nd textField is tapped, cause the 2nd becomes first responder and the 1st suffers a "resignFirstResponder".
I suggest trying to use a UITapGestureRecognizer in your textField instead. Example:
Swift 4
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.tag = 1
self.textField.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(fireTextField(_:))))
}
#objc func fireTextField(_ sender: UIGestureRecognizer){
let view = sender.view
guard view != nil else{
//Do nothing
return
}
let condition = view!.tag == 1
if condition{
//or do whatever other stuff you need
self.textField.becomeFirstResponder()
}else{
//Whatever for other textFields
}
}
This way, you could use the "tag" attribute to determine which textField is firing and so adjust "condition". You could also filter the flow with a switch using the "tag".
Not sure if any of this will really help as I would need more info about the flow you need to accomplish. Hope it does help!
I have a textfield on a form where the value changes based on the slider. I am trying update the functionality so that when the user enters a value in the text field the slider will move to the correct position. My UISlider will be a value between 0 and 3.
I have been trying to use this post to help me but, I have not been able to get it to work: How to set value of UISlider from a UITextField
Cheers,
I want the user to be able to use the slider or keyboard to enter the rate discount - but if they enter a value I want the slider to move to the right spot. Using the code given the app crashes. I think it's because of conflicting code. I have been linking the sider as an outlet. Is this correct?
Are you failing because yoru link is an Objective C version? So here is the swift equivalent. First, add a listener on your textfield like this
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
Then in your text field text change function, set value for your slider
func textFieldDidChange(textField: UITextField) {
if let stringValue = textField.text{
if let intValue = Int(stringValue){
slider.setValue(intValue, animated: true)
}
}
}
I am trying to build a zodiac sign app for class. I am using a UIDatePicker and an UIImageView to display the image once the user picks a date (date range, say if the date of birth is between a certain date). The zodiac will be revealed in text and also the image appears. So far I have my user interface and all the images ready, but I am not sure how to go with the main code for it to function properly.
var zodiac = ["Aqurius", "Pisces", ...]
override func viewDidLoad() {
zodiacSign.text = zodiac[0]
}
Add an #IBAction by ctrl-dragging from your UIDatePicker in Interface Builder to your view controller.
#IBAction func datePickerChanged(sender: AnyObject) {
let date = datePicker.date
// configure your labels and images according to date
}
I'm implementing a favourite button in swift for my quote application. Since I want to disable the user to be able to favourite a quote twice. I must change the text to unlike and then compare the button text mode being unlike to the button text mode being like. And then do furthermore things based on these conditions. It would look something like:
#IBAction func favour(sender: AnyObject) {
if liketext.text == "Like"{
liketext.setTitle("Unlike", forState: UIControlState.Normal)
makeQuoteFavourite()
} else if liketext.text == "Unlike" {
liketext.setTitle("Like", forState: UIControlState.Normal)
}
}
However as many of you know, a button outlet cannot have the .text function. #IBOutlet var liketext: UIButton! How would I be able to compare button strings to normal strings? Are there other possible solutions?
UIButtons simply work differently than UILabels. They have control states for one thing. And their (title) text can be set on a per-control-state basis.
So you have to use the currentTitle property:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIButton_Class/#//apple_ref/occ/instp/UIButton/currentTitle
or the titleForState method:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIButton_Class/#//apple_ref/occ/instm/UIButton/titleForState:
Now those titles are normal String objects; it's the name of the property that's different.