48 votes

iOS 7 - Animation du clavier

J'essaie de comprendre la nouvelle animation du clavier dans iOS 7.0 sur le simulateur de l'iPhone 5. Je veux redimensionner mon UITableView lorsque le clavier apparaît, mais je n'arrive pas à obtenir les bons détails de l'animation.
J'utilise les informations de la NSNotification lorsque le clavier apparaît ou disparaît.

Voici mon journal :

Move keyboard from {{0, 920}, {320, 216}} to {{0, 352}, {320, 216}}
 with duration: 0.400000
 and animation curve: 7

UIViewAnimationCurveEaseInOut = 0
UIViewAnimationCurveEaseIn = 1
UIViewAnimationCurveEaseOut = 2
UIViewAnimationCurveLinear = 3

La courbe d'animation est une valeur inconnue, que dois-je faire ?

0 votes

Vérifiez si cela résout votre problème stackoverflow.com/questions/11313951/

0 votes

Désolé, j'ai oublié d'écrire que j'utilise une UIViewController avec un UITableView subview.

0 votes

Quels sont les détails de l'animation que vous attendez ?

72voto

David Beck Points 4329

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

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];

// work

[UIView commitAnimations];

Bien que les animations basées sur des blocs soient recommandées, la courbe d'animation renvoyée par la notification du clavier est un élément de l'animation. UIViewAnimationCurve alors que l'option que vous devez passer pour les animations basées sur des blocs est une option de type UIViewAnimationOptions . L'utilisation des méthodes d'animation traditionnelles de UIView vous permet de canaliser la valeur directement dans. Plus important encore, cela utilisera la nouvelle courbe d'animation non documentée (valeur entière de 7) et fera en sorte que l'animation corresponde au clavier. . Et, il fonctionnera tout aussi bien sur iOS 6 et 7.

2 votes

Fonctionne parfaitement sur UIKeyboardWillShowNotification mais lorsque l'on quitte le clavier par UIKeyboardWillHideNotification mon UIView semble être désynchronisé par rapport au clavier.

0 votes

Est-il légal d'utiliser une courbe d'animation non documentée ? Apple rejettera-t-il votre application si vous faites cela ?

0 votes

1) Il est probable que cela ne sera jamais pris en compte par Apple, mais en général, ce serait une mauvaise idée de l'utiliser directement. 2) Nous ne l'utilisons pas directement ici. Nous passons naïvement la valeur qui nous est donnée.

47voto

Paul A. Warkentin Points 1853

J'ai maintenant trouvé la solution. L'animation commence à partir du point {0, 920} a {0, 352} . Le problème était que le UITableView a commencé avec une taille de {160, 568} J'ai donc modifié la taille de la UITableView a {160, 920} avant que l'animation ne soit lancée.

En ce qui concerne la courbe d'animation inconnue, j'ai simplement défini le paramètre à animationCurve << 16 pour la convertir d'une courbe d'animation de vue en une option d'animation de vue.
La valeur n'est pas égale à la courbe d'animation linéaire, d'entrée, de sortie et de sortie.

Voici mon code :

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(_keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];

et :

- (void)keyboardWillShow:(NSNotification *)aNotification {
    NSDictionary *userInfo = aNotification.userInfo;

    //
    // Get keyboard size.

    NSValue *beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardBeginFrame = [self.view convertRect:beginFrameValue.CGRectValue fromView:nil];

    NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];

    //
    // Get keyboard animation.

    NSNumber *durationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration = durationValue.doubleValue;

    NSNumber *curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey];
    UIViewAnimationCurve animationCurve = curveValue.intValue;

    //
    // Create animation.

    CGRect tableViewFrame = self.tableView.frame;
    bTableViewFrame.size.height = (keyboardBeginFrame.origin.y - tableViewFrame.origin.y);
    self.tableView.frame = tableViewFrame;

    void (^animations)() = ^() {
        CGRect tableViewFrame = self.tableView.frame;
        tableViewFrame.size.height = (keyboardEndFrame.origin.y - tableViewFrame.origin.y);
        self.tableView.frame = tableViewFrame;
    };

    //
    // Begin animation.

    [UIView animateWithDuration:animationDuration
                          delay:0.0
                        options:(animationCurve << 16)
                     animations:animations
                     completion:nil];
}

1 votes

"Concernant la courbe d'animation inconnue, j'ai juste défini le paramètre à animationCurve << 16 pour la convertir d'une courbe d'animation de vue en option d'animation de vue." Comment en êtes-vous arrivé là ?

1 votes

Voir la définition de UIViewAnimationOptionCurveEaseIn par exemple dans UIView.h

9 votes

Ce genre de choses est incroyablement frustrant. C'est quoi ce bordel, Apple ? Merci.

12voto

Anton Gaenko Points 331

Vous pouvez utiliser animateWithDuration et définir la courbe à l'intérieur de celui-ci. C'est propre et ça marche 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];

Bon codage !

UPDATE

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

5voto

Jeffrey Sun Points 99

Utilisez UIKeyboardWillChangeFrameNotification à la place, car certains claviers internationaux, comme le clavier chinois, changent de hauteur en cours d'utilisation. Ce code vous donne également les hauteurs correctes pour le clavier, même en mode paysage. (Note : le code ci-dessous est pour Autolayout )

//set your observer, in a method like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];

- (void)keyboardWillChange:(NSNotification *)notification {
    CGRect initialRect = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
    CGFloat initialHeight = self.view.frame.size.height - [self.view convertRect:initialRect fromView:nil].origin.y;
    CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat newHeight = self.view.frame.size.height - [self.view convertRect:keyboardRect fromView:nil].origin.y;
    //set your constraints here, based on initialHeight and newHeight, which are the heights of the keyboard before & after animation.
    [self.contentView setNeedsUpdateConstraints];
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [self.contentView layoutIfNeeded];
    [UIView commitAnimations];
}

1 votes

Propre. Le site swift La version est ici stackoverflow.com/questions/24923086/

4voto

Anton Anisimov Points 2273

Pour utiliser la même animation que celle du clavier, vous devez utiliser l'option non documentée Curve.

- (void)keyboardWillHide:(NSNotification *)notification {
    NSDictionary *userInfo = [notification userInfo];

    CGRect rect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    NSTimeInterval animationDuration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    NSInteger curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16;

    [UIView animateWithDuration:animationDuration delay:0.0 options:curve animations:^{

    } completion:nil];
}

J'ai trouvé cette méthode en fait animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion: est la nouvelle façon dont toutes les animations sont réalisées dans iOS7 et iOS8 maintenant. Il suffit de choisir la bonne durée, l'amortissement et la vitesse pour obtenir le même effet, mais vous pouvez également modifier la vitesse et le temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X