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.
Related
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 am trying to get the text from a UITextView whose entry method was dictation. In the textViewDidChange delegate method, I have tried printing the following info:
print(textView.text)
print(myTextView.text)
print(textView.hasText)
print(textView.attributedText)
print(textView.textStorage)
all of these come back nil, except the hasText comes back as false.
The text is visible right there in the textView, but it is not being registered. I should say that when I go edit another form in the field, and then try to get the value from this text field, then the the text entered IS visible in the textView's textView.text property. But it's like it takes a few moments of editing other fields to fully "register" with the textView object.
Any idea what could be happening here?
Try this after a while
let when = DispatchTime.now() + 0.5
DispatchQueue.main.asyncAfter(deadline: when) {
print(textView.text)
print(textView.hasText)
print(textView.hasText)
print(textView.attributedText)
print(textView.textStorage)
}
Update: It`s because you are trying to print the text before setting it. It takes a little time to set your text into textView.
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.
I am implementing a message composer as like iMessages.
enablesReturnKeyAutomatically of UITextView is not working.
I have set it as textView.enablesReturnKeyAutomatically = YES;
but when I tap on numeric keypad and start typing something and sent using my send button. the textView got empty but the send button (return button of UITextView) is still enabled.
enablesReturnKeyAutomatically seems to only affect the uikeyboard, which in this case is a numeric keypad. The default numeric keypad does not have a return key, so there is nothing to enable/disable.
It sounds like you have a separate send button in the view. A workaround is inside - textView:shouldChangeTextInRange:replacementText: calculate what the new string will be with the replacementText and test if this new String is equal to #"". If so, then sendButton.enabled = NO, else sendButton.enabled = YES.
Remember to set the UITextViewDelegate and to trim the new string of white space.
I created a custom keyboard in Swift but it was rejected from the App Store because: "keyboard extension does not include Number and Decimal types".
How can I add these two keyboards easily?
I tried to rebuild the original view but it doesn't work properly. I'm sure there is a solution to create 2 or 3 different views and switch between them.
How can I switch between keyboard types when the keyboard type changes?
You can detect changes to the keyboard type in textDidChange. You need to get the UITextDocumentProxy then detect the proxy's keyboardType, and then you can do whatever layout changes needed.
override func textDidChange(_ textInput: UITextInput?) {
// Called when the document context is changed - theme or keyboard type changes
let proxy = self.textDocumentProxy as UITextDocumentProxy
if proxy.keyboardType == UIKeyboardType.numberPad
|| proxy.keyboardType == UIKeyboardType.decimalPad {
//add code here to display number/decimal input keyboard
}
}