Comment imiter l'animation du keyboard sur iOS 7 pour append le button "Terminé" au keyboard numérique?

J'avais fait quelque chose comme ça pour imiter l'animation du keyboard sur une ancienne version d'iOS.

CGRect keyboardBeginFrame; [[note.userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] getValue:&keyboardBeginFrame]; self.doneKeyboardButton.frame = CGRectMake(0, (keyboardBeginFrame.origin.y + keyboardBeginFrame.size.height) - 53, 106, 53); [[[[UIApplication sharedApplication] windows] lastObject] addSubview:self.doneKeyboardButton]; CGPoint newCenter = CGPointMake(self.doneKeyboardButton.superview.frame.origin.x + self.doneKeyboardButton.frame.size.width/2, self.doneKeyboardButton.superview.frame.size.height - self.doneKeyboardButton.frame.size.height/2); [UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]-.02 delay:.0 options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] animations:^{ self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -TextFieldViewMovement); self.doneKeyboardButton.center = newCenter; } completion:nil]; 

Cependant, cela a cessé de fonctionner sur iOS7. Il semble que les valeurs renvoyées ne sont plus tout à fait correctes, et le button Terminé ne reproduit plus exactement l'animation d'affichage du keyboard.

Dans iOS 7, le keyboard utilise une nouvelle courbe d'animation non documentée. Alors que certains ont noté que l'utilisation d'une valeur non documentée pour l'option d'animation fonctionne, je préfère utiliser ce qui suit:

 [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]]; [UIView setAnimationBeginsFromCurrentState:YES]; // work [UIView commitAnimations]; 

Bien que les animations basées sur des blocs soient la recommandation, la courbe d'animation renvoyée par la notification par keyboard est une UIViewAnimationCurve , tandis que l'option que vous devez passer aux animations basées sur des blocs est une UIViewAnimationOptions . L'utilisation des methods d'animation UIView traditionnelles vous permet de diriger directement la valeur. Plus important encore, ceci utilisera la nouvelle courbe d'animation non documentée (valeur entière de 7) et fera correspondre l'animation au keyboard . Et, cela fonctionnera aussi bien sur iOS 6 et 7.

J'ai eu le même problème et j'ai réussi à faire fonctionner l'animation avec les parameters suivants pour iOS 7:

  [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:500.0f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveLinear animations:animBlock completion:completionBlock]; 

EDIT: ces valeurs ont été obtenues par debugging, et peuvent changer avec les nouvelles versions d'iOS. @ La réponse de DavidBeck fonctionne pour moi dans iOS 7 aussi donc je le relie ici.

Apple utilise une animation non documentée avec la valeur 7 dans iOS 7.

Cependant, la déclaration de UIViewAnimationCurve définit des valeurs de 0 à 3

 typedef enum { UIViewAnimationCurveEaseInOut, // 0 UIViewAnimationCurveEaseIn, UIViewAnimationCurveEaseOut, UIViewAnimationCurveLinear // 3 } UIViewAnimationCurve; 

Les UIViewAnimationOptions vous avez besoin pour les animations par bloc sont définies comme

 enum { // ... UIViewAnimationOptionCurveEaseInOut = 0 << 16, UIViewAnimationOptionCurveEaseIn = 1 << 16, UIViewAnimationOptionCurveEaseOut = 2 << 16, UIViewAnimationOptionCurveLinear = 3 << 16, UIViewAnimationOptionTransitionNone = 0 << 20, // ... }; 

Il semble qu'Apple réserve 4 bits pour la courbe animaton (20 – 16 = 4) qui permet des valeurs de 0 à 15 (donc il y a probablement plus de valeurs non documentées).

Avec cette connaissance, vous pouvez simplement transformer un UIViewAnimationCurve en UIViewAnimationOptions en le décalant d'environ 16 bits. Dans votre exemple, cela signifie:

 options:[[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16 

Vous pouvez utiliser le bloc animateWithDuration et définir la courbe à l'intérieur. C'est propre et fonctionne bien.

 UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]; double duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ [UIView setAnimationCurve:curve]; /* ANIMATION HERE */ // don't forget layoutIfNeeded if you use autolayout } completion:nil]; 

Codage heureux!

METTRE À JOUR

Vous pouvez utiliser une simple catégorie UIViewController écrite par moi https://github.com/Just-/UIViewController-KeyboardAnimation

Si vous voulez append le button dans une barre d'outils (de la même manière que Safari mobile le fait), vous pouvez simplement utiliser la propriété inputAccessoryView (à la fois UITextField et UITextView ) et vous épargner tous les problèmes. Ce joyau caché est peu connu, je suis heureux d'y être tombé dessus.

Il fonctionne sur iOS 6 et iOS 7, je l'utilise dans mon application Routie .

Cela fonctionne très bien pour moi … La durée est attrapée lorsque le keyboard est affiché. Je sais que le encoding en dur des options signifie qu'il pourrait se casser dans le futur, mais cela fonctionne pour 7 et 8. C'est assez bon pour nous pour l'instant …

 [UIView animateWithDuration:self.animationDuration delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ [self.view layoutIfNeeded]; completion:^(BOOL finished) { if (finished) { if (completion) completion(); } }];