12

Attualmente ho un UITextField sulla parte superiore di una tastiera. Quando lo tocchi, dovrebbe rimanere sulla parte superiore della tastiera e spostarsi senza problemi. Non conosco la durata esatta e il tipo di animazione della tastiera, quindi è davvero sconnessa. Ecco quello che ho:Mantenere un oggetto sulla tastiera in caso di becomeFirstResponder o resignFirstResponder?

[theTextView resignFirstResponder]; 
[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDuration:0.25]; 
[UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
// Frame changes go here (move down 216px) 
[UIView commitAnimations]; 

[theTextView becomeFirstResponder]; 
[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDuration:0.25]; 
[UIView setAnimationCurve:UIViewAnimationCurveLinear]; 
// Frame changes go here (move up 216px) 
[UIView commitAnimations]; 

se qualcuno ha fatto qualcosa di simile prima, vorrei conoscere le impostazioni utilizzate per rendere l'animazione liscio e far sembrare che il bar è "bloccato" in cima la tastiera.

risposta

44

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]; 
} 
+1

Grazie. Grazie. Grazie. Grazie. Con una piccola modifica, ho funzionato e sembra super slick. – iosfreak

+0

@rob mayoff il problema è quando ho un 'UITabBar'. Quando la tastiera nasconderà 'UITextField' scorre verso il basso sotto' UITabBar'. Perché? –

+0

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. –

0

per rendere UITextField ancorabile alla tastiera (con animazione), è necessario eseguire calcoli di offset e applicare le modifiche di offset nella vista di scorrimento (presupponendo che UITextField sia inserito in UIScrollView) utilizzando il metodo setContentOffset:animation:.

+0

Non è in ScrollView. Una scrollView non esiste nemmeno, è un UITableView. – iosfreak

+2

@ phpnerd211: UITableView è una sottoclasse di UIScrollView. – Andrew

5

Impostare il campo di testo (o una vista che tiene il campo di testo) come inputAccessoryView del campo che stai modificando. Sarà quindi automaticamente collegato alla parte superiore della tastiera e animato in modo appropriato.

Problemi correlati