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