web-dev-qa-db-fra.com

iOS 7 - Animation du clavier

J'essaie de comprendre la nouvelle animation de clavier sous iOS 7.0 sur le simulateur iPhone 5. Je souhaite redimensionner ma UITableView lorsque le clavier apparaît, mais je ne peux pas obtenir les détails d'animation appropriés.
J'utilise les informations de l'objet 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?

46
Paul Warkentin

Maintenant j'ai trouvé la solution. L'animation commence du point {0, 920} à {0, 352}. Le problème était que l'objet UITableView avait démarré avec une taille de {160, 568}. J'ai donc modifié la taille de UITableView en {160, 920} avant le démarrage de l'animation.

En ce qui concerne la courbe d'animation inconnue, je viens de définir le paramètre sur animationCurve << 16 pour le 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, atténuation, atténuation et atténuation.

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];
}
47
Paul Warkentin

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

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

// work

[UIView commitAnimations];

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

72
David Beck

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];

Bonne codage!

METTRE &AGRAVE; JOUR

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

12
Anton Gaenko

Utilisez plutôt UIKeyboardWillChangeFrameNotification, car certains claviers internationaux, comme le clavier chinois, changent de hauteur pendant l’utilisation. De plus, ce code vous donne les hauteurs correctes pour le clavier, même en mode paysage. (Remarque: 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];
}
5
Jeffrey Sun

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

- (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 découvert qu'en réalité la méthode animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion: est la nouvelle façon dont toutes les animations sont réalisées dans iOS7 et iOS8. Vous faites juste la bonne durée, l’amortissement et la vélocité et vous obtiendrez le même effet, mais même vous pourrez changer la vitesse/le temps.

4
invoodoo

Inscrivez-vous pour la notification:

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

Répondez en animant une modification du frame.Origin.y de la vue.

- (void)keyboardWillShow:(NSNotification *)aNotification {

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

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

    CGRect searchButtonFrame = self.searchButton.frame;
    searchButtonFrame.Origin.y = (keyboardEndFrame.Origin.y - searchButtonFrame.size.height);
    self.searchButton.frame = searchButtonFrame;

    [UIView commitAnimations];
}
0