UITextField has an inputView property that can be used to specify a custom keyboard. Clearing this to nil provides the default keyboard.
If the UITextField is the first responder, no change occurs on setting inputView, but by calling [textField reloadInputView] the keyboard change will happen immediately.
I'd like to be able to switch between two different input approaches. The interface to trigger this will be a UISegmentedView installed as the UITextField's inputAccessoryView.
I've got this working, but the transition is very abrupt. Partly because the spinner and keyboard I transition between have different sizes on the iPad.
I've found that is I wrap an animation block around reloadInputView, I will get a smooth animation between the two keyboard's view frames. Unfortunately there is a visual judder because the transition is not animated:
[UIView animateWithDuration: 0.3 animations:^()
{
[firstResponder reloadInputViews];
}];
Alternatively, if I wrap the reload in a transition, I can get a nice cross fade, but I don't get smooth frame changes:
[UIView transitionWithView: keyboardWindow
duration: 0.3
options: UIViewAnimationOptionTransitionCrossDissolve
animations: ^(){ [firstResponder reloadInputViews]; }
completion: nil];
(In the second code block I obtained keyboardWindow from self.window because this view is installed as the UITextField's inputAccessoryView which is ultimately nested under the keyboard's window.)
What I'd like is to animate and transition the input view reload. I tried placing reload in a transition in an animation, and I also tried placing the reload in an animation in a transition – neither seemed to help.
Any ideas? Thanks!
You can invoke resignFirstResponder to make the input view disappear and then invoke becomeFirstResponder, after a delay, to make the keyboard appear and vice versa.
The following sets to inputView after resigning the normal keyboard.
let delayTime = dispatch_time(DISPATCH_TIME_NOW,Int64(1 * (NSEC_PER_SEC/3)))
textField.resignFirstResponder()
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.textField.inputView = currentInputView
self.textField.becomeFirstResponder()
}
This sets to keyboard.
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.textField.inputView = nil
self.textField.becomeFirstResponder()
}
I'm able to successfully animate changes to an inputView without any glitches by:
inputView as a subview of the existing inputView and then UIControl's inputView to the custom inputView after your choice of animation is complete.As an example, here's how to quickly fade in a custom inputView:
//start the view as invisible
_customInputView.alpha = 0.0f;
//add the custom inputView as a subview of the existing inputView
[self.inputView addSubview:_customInputView];
//animate the opacity change
[UIView animateWithDuration:0.25f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
_customInputView.alpha = 1.0f;
} completion:^(BOOL finished) {
//switch the UIControl's inputView
self.inputView = _customInputView;
}];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With