I want to hide the keyboard if the user clicks on a textfield. Does anybody have an idea how to do that in swift 2?
Make sure to set the text field delegate and return false in this UITextFieldDelegate method:
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
return false
}
This will prevent the keyboard from showing. You can also place the code to open the picker in that method.
Showing a text field on screen doesn't mean that only a text field is there. You could have a text field as a sub view, with user interaction disabled. Then, add a transparent button as a sibling view with the same frame (ensuring it's in front). When the button is tapped, which from a user point of view is tapping the text field, you can show your picker.
The text field also offers direct support for displaying a picker view by allowing you to set its inputView.
Related
I was wondering how I would be able to go about changing the status of buttons. I want to make it if one of two text fields has text in them then the button will become useable. I have currently turned off the button from the storyboard. The code I have to check if there is text inside of the text fields is as follows:
Disclaimer:
The code to check if the text field has any text in it works perfectly fine.
#IBAction func textFeildEditingChanged(_ textField: UITextField) {
if FirstName.hasText == true {
self.navigationItem.rightBarButtonItem?.isEnabled = true
print("First name isn't empty")
}
}
The current code that I have in there to set the button to enabled and disable doesn't work however the code to test if the text field has content does work. I just need to figure out how to disable and enable the button of a navigation item.
code that doesn't work is below:
self.navigationItem.rightBarButtonItem?.isEnabled = true
Any help would be greatly appreciated.
Edit: I am using a navigation controller, don't know if that's important or not.
If you are using the storyboard, just connect the outlet then disable it.
#IBOutlet var navigationItemButton: UIBarButtonItem!
then
navigationItemButton.isEnabled = FirstName.hasText
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 UITextView subclass where I specifically disable all context menu options:
class MyTextView: UITextView {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
}
I add an instance of MyTextView to a view that shows up in my app. I give the instance of MyTextView the following value: isEditable = false
When I long press on the UITextView however, I get the following:
This seems like a bug since there is nothing in this menu? Any ideas on how to prevent this?
Thanks!
Because selectable property is active. So you can "select" a part of text and iOS default behaviour is to show this popover.
You can disable this property by storyboard, or by code.
Storyboard:
At storyboard, select the textview and go to attribute inspector tab... Search for behavior and uncheck selectable checkbox.
or, if you prefer, you can solve it by code:
at viewDidLoad method, set the property isSelectable to false.
MyTextView.isSelectable = false
That's not "the menu". It's just the thing that magnifies the region where the press occurs:
It's empty in your screen shot only because you've no text, so we're magnifying nothing. The menu appears after your long press ends and the magnifier thing goes away — and it doesn't appear, so your code is working fine.
You can see easily that that's true by changing your code to return true. The empty magnifier will appear, just as it does now, and then when it disappears, the menu appears. Thus, we have proved that what you are seeing is not "the menu".
I have a static numeric-keyboard made out of a bunch of buttons, I also have three UITextFields, textField1, textField2 and textField3 where I'm inputting the text using the static keyboard.
Here is the code I'm using to detect which textField is currently in focus and to input the content of the buttons. It kind of works but I don't like the fact that I have three IF statements and I'm not sure how to prevent the keyboard from appearing when a textField is tapped.
What would be the best way to implement this functionality?
#IBAction func appendKey(sender: AnyObject) {
let digit = sender.currentTitle!
if(textField1.isFirstResponder()){
textField1.text = textField1.text! + digit!
}else if(textField2.isFirstResponder()){
textField2.text = textField2.text! + digit!
}else if(textField3.isFirstResponder()){
textField3.text = textField3.text! + digit!
}
}
Thanks
If the standard keyboard is displaying then your custom keyboard isn't setup properly. Your custom keyboard should be the inputView of each UITextField. If you do that, the standard keyboard won't appear and yours will instead.
Your custom keyboard should be a separate class that handles all of it's own buttons. It appears you have everything in one view controller - all of the text fields, all of the buttons, and all of the button handling code. This is a bad approach. Create your custom keyboard class view. Put all of the code to handle and display the buttons in that custom view class. Create a single instance of this view in your view controller and assign the custom keyboard view instance to the inputView property of each text field.
In the custom keyboard class, listen for the UITextFieldTextDidBeginEditingNotification notification. This is how you keep track of the current text field. Your custom keyboard class should not have any specific reference to any text field other than track the current one. It should also ensure that the text field's inputView is itself.
In each button handler of the custom keyboard class, get the text you wish to append and then call the text field's insertText: method with the string. That's it. This will ensure the text is inserted and/or replaced based on the current selecting in the text field.
I am trying to understand delegate methods in general, and specifically how to dismiss a UIDatePicker that popovers from a text field.
According to the documentation, textFeildShouldBeginEditing returns true 'if an editing session should be initiated; otherwise, false to disallow editing.'
Why would I then tell the app to resignFirstResponder, which is meant to hide the keyboard / date picker (as in several examples on stackoverflow and noobie tutorials)?
What I don't understand is: if it should begin editing, why then hide the input devise? Obviously, I am misunderstanding one or both concepts.
func resign() {
dobTextField.resignFirstResponder()
nameTextField.resignFirstResponder()
println("resign gets printed, but the date picker is still visible!?!")
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if (textField === dobTextField) {
resign() // but should begin editing, oder?!?
}
In the examples you cite, the textField is being used to display a date. When the user selects this field, the app designers want the UIDatePicker to be displayed instead of the keyboard. Hence they call resignFirstResponder to hide the keyboard. At the same time, they display the date picker.
ResignFirstResponder will not hide the date picker, so the "input device" (for this field) will still be available.
Also, note that in one case the developer has used textFieldShouldBeginEditing, and returns false because they are providing the date picker. In the other case the developer uses textFieldDidBeginEditing (which has no return value).
you should resign only the textfield not affected:
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if textField == dobTextField {
nameTextField.resignFirstResponder()
} else if textField == nameTextField {
dobTextField.resignFirstResponder()
}
return true
}
this way you are resiging first responder only on the textfields that should not currently be edited. this helps if for some reason you accidentally have 2 textfields (or more) assigned first responder causing conflicts with multiple keyboards/datepickers and such.