Post UIKit UIKeyboardWillShowNotification
quando mostra la tastiera e UIKeyboardWillHideNotification
quando nasconde la tastiera. Queste notifiche contengono tutto il necessario per animare correttamente il tuo UITextField
.
Supponiamo che il tuo UITextField
si trovi in una proprietà chiamata myTextField
.
In primo luogo, è necessario registrarsi per le notifiche da qualche parte. Dove si registra dipende da quale oggetto è responsabile dello spostamento di myTextField
. Nel mio progetto, superview del campo è responsabile, e dato che io carico la mia UI da un pennino, lo faccio nel del superview awakeFromNib
:
- (void)awakeFromNib
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHideOrShow:) name:UIKeyboardWillShowNotification object:nil];
}
Se si utilizza un UIViewController
per spostare il campo intorno, probabilmente voglio farlo in viewWillAppear:animated:
.
Si dovrebbe annullare la registrazione nel vostro dealloc
o viewWillDisappear:animated:
:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Naturalmente il po 'complicato è nel metodo keyboardWillHideOrShow:
. Per prima cosa ho estrarre i parametri di animazione dalla notifica:
- (void)keyboardWillHideOrShow:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
Il keyboardFrame
è nel sistema di coordinate globale. Devo convertire il telaio per lo stesso sistema di coordinate come myTextField.frame
, e myTextField.frame
è nel sistema di coordinate di myTextField.superview
:
CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];
Successivamente, calcolare il telaio che voglio myTextField
per spostarsi. Il bordo inferiore del nuovo telaio dovrebbe essere uguale al bordo superiore del telaio della tastiera:
CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;
Infine, animare myTextField
al suo nuovo telaio, utilizzando gli stessi parametri di animazione che utilizza la tastiera:
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.myTextField.frame = newTextFieldFrame;
} completion:nil];
}
Qui è tutto messo insieme:
- (void)keyboardWillHideOrShow:(NSNotification *)note
{
NSDictionary *userInfo = note.userInfo;
NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];
CGRect keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect keyboardFrameForTextField = [self.myTextField.superview convertRect:keyboardFrame fromView:nil];
CGRect newTextFieldFrame = self.myTextField.frame;
newTextFieldFrame.origin.y = keyboardFrameForTextField.origin.y - newTextFieldFrame.size.height;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{
self.myTextField.frame = newTextFieldFrame;
} completion:nil];
}
Grazie. Grazie. Grazie. Grazie. Con una piccola modifica, ho funzionato e sembra super slick. – iosfreak
@rob mayoff il problema è quando ho un 'UITabBar'. Quando la tastiera nasconderà 'UITextField' scorre verso il basso sotto' UITabBar'. Perché? –
Se si dispone di una barra delle schede, quando si nasconde la tastiera è necessario calcolare 'newTextFieldFrame' in base al frame della barra delle schede anziché al frame della tastiera. –