Animating UITextInput's textInputView - ios

UIKit text input components, such as UITextView and UITextField have a property inputView to add a custom keyboard. There are two questions I have relating to this.
If the keyboard is currently visible and the property is set to a new input view, nothing happens. Resigning and regaining first responder status refreshes the input and displays the new view. Is this the best way to do it? If so it might answer my bigger question:
Is it possible to animate the transition between two input views?

From the UIResponder docs:
Responder objects that require a custom view to gather input from the user should redeclare this property as readwrite and use it to manage their custom input view. When the receiver subsequently becomes the first responder, the responder infrastructure presents the specified input view automatically. Similarly, when the view resigns its first responder status, the responder infrastructure automatically dismisses the specified view.
So unfortunately the answer to 1 is Yes and 2 is No.

Actually there is a method to do it cleanly: UIResponder's reloadInputViews, available from iOS 3.2!
I think you can animated it with some extra work:
Create a clear background window of a higher UIWindowLevel than the keyboard window.
Add your custom keyboard there and animate its frame into place.
Then set it as your text input's inputView and refresh the first responder as you do.
Your custom keyboard will change its parent view from your custom window to the keyboard one, but hopefully the user won't notice ;)

Related

UIView isHidden function, what does "the view's next valid key view" means?

I'm currently studying the isHidden method of UIView class.
In the Apple documentation, it mentioned
Hiding the view that is the window’s current first responder causes
the view’s next valid key view to become the new first responder.
I was just wondering, what does the view's next valid key view means?
That documentation is apparently left over from the older NSView documentation and it is incorrect.
NSView is the macOS equivalent of iOS's UIView. NSView has a nextKeyView property which indicates what view should get keyboard focus when the user tabs out of the current view. NSView also has a computed property, nextValidKeyView, which is the next view in the key view loop that accepts first responder and is not hidden.
UIView has no nextKeyView or nextValidKeyView property.
Furthermore, on iOS, hiding the current first responder does not cause “the view’s next valid key view to become the new first responder”, for any reasonable definition of “next valid key view”, because the hidden view remains first responder.
Here's a demo, recorded on a real iPhone 6 (not the simulator) running iOS 10.3.2. The “Button” toggles the isHidden property of the top text field.
After I type “hello” in the top text field, I tap the button to hide that text field. The keyboard is still active but the second text field has no blinking insertion point. I then type “world” and tap the button again. The top text field reappears, and now it says “hello world”. It continued to be first responder while it was hidden. The second text field (which is the only possible candidate for “next valid key view”) did not become first responder.
Causes that the next valid key (the next view of the stack) will be the responder, which if there is nothing "behind" that view that you are hiding will be the super view.

iOS Custom keyboard can't return focus to app's textfield

I'm working on a custom keyboard for iOS which will have its own search field (similarly implemented by PopKey).
My keyboard's textfield is able to take the focus with becomeFirstResponder and I'm able to give it up by using resignFirstResponder. However after I resign focus, the host app has a difficult time retaking focus despite touching the form. The app's textfield will still show the text cursor blinking.
Any ideas? Thanks
The solution is a hack, as of right now you can't really give the host app its focus back.
Subclass a UITextField and on its delegate implement
textFieldShouldBeginEditing by returning NO.
Add a BOOL property isSelected that gets set to YES in touchesBegan (not to be confused with the default selected property)
In your keyboard's keyPressed method, if searchField.isSelected, manipulate the searchField.text. Else, manipulate textDocumentProxy like normal.
Add a clear button and method that wipes searchField.text and searchField.isSelected, allowing any further keystrokes to return to the textDocumentProxy
Add an animation that replicates the blinking type cursor

Swap out a custom inputView for the standard keyboard in iOS

I have a custom inputView for a particular textfield, and it works well. However, I cannot discern how to dismiss the view and get the regular keyboard back. (I have a SWAP button right next to the TextField.) I tried setting the textfield's inputView to nil, but that did nothing.
I do not need a full custom keyboard, but I need more than an Accessory view above the keyboard, which is why I am trying this route. I need about 20 custom buttons in addition to the regular keyboard, and I do not like the idea of a huge Accessory view taking up so much space.
I also would rather not require the user to initially install a full custom keyboard before being able to use the app.
Thank you very much for any suggestions.
I think you will probably have to do this:
Call resignFirstResponder on the UITextField
After the animation finishes, set your inputView to nil
Call becomeFirstResponder on the text field
The keyboard animation duration is sent in the userInfo dictionary on the keyboard presentation notifications.
In addition to the accepted answer, you can use reloadInputViews() (and this is less likely to suffer any animation glitches resulting from the resignFirstResponder, becomeFirstResponder calls):
yourTextField.inputView = nil;
yourTextField.reloadInputViews();
Here's more info in the Apple's Docs.

Prevent iOS keyboard from disappearing / reappearing between UITextFields?

I've got a form with some UITextField instances, and I've set up an accessory view to flip back and forth between them as you fill in the form. The ugliness is that the keyboard slides away, then immediately slides back for the next form.
Since it's going to remain there, is there a way to get it to simply stay up throughout the whole form, rather than this ugly/silly gone/back behaviour? I may be doing something wrong programmatically, I'm telling fields to resignFirstResponder before the new one does becomeFirstResponder – is that the cause?
You don't need to called resignFirstResponder when switching between text fields, iOS will handle this for you when calling becomeFirstResponder on another object. You just need to call resignFirstResponder if/when you want to hide the keyboard, say at the end of the form.
Yes, that is the cause. You can just call becomeFirstResponder without calling resignFirstResponder and you'll get what you want
When you select other UITextField than automatically the last UITextField resign first responder so you should not resignFirstResponder every time. Just resign when you done with UITextField or user click on the UIView.

UITextField not receiving touch event

I have a UITextField in a complex view hierarchy. The text field is in a UIView with label and textfield, say, labelfield.
I can type text there.
There is info button on top right corner. When tap on Info, a modal view controller is loaded. When coming back from the modal view controller, the UITextField becomes unresponsive. I cannt type anything there. The labelfiedl is drawn and shown in the screen.
Interesting thing is that, if I press the ok button, and alert is shown and then the textfield becomes active. Also, on top of the view, there is some text with user interaction enable, if I tap and try to select the text and after that the textfield becomes active. Seems I have to do some other activity/touch on the super view, then the text field becomes active.
Why not on the first case it receive any touch event? I tried with textField.enabled, becomesFirstResponder, setNeedsDisplay in the viewDidApper method, nothing works.
Try the following...
Make sure that the super view to which the text field is added as subview large enough to contain text field(ie make sure that no part of text field is out side the superview. check this for all views).
Make sure that there is no view above textfield.use bringSubViewToFront: method.
Try to enable use interaction after a delay
Hope any of the above fix will solve your problem

Resources