web-dev-qa-db-fra.com

Contrainte de mise en page automatique - Clavier

Im bloqué en essayant d'animer une vue de table en douceur qui a une contraint de mise en page automatique. J'ai une référence à la contrainte "keyboardHeight" dans mon .h et j'ai lié cela dans IB. Tout ce que je veux faire, c'est animer la vue de la table avec le clavier lorsqu'elle apparaît. Voici mon code:

- (void)keyboardWillShow:(NSNotification *)notification
{
    NSDictionary *info = [notification userInfo];
    NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [kbFrame CGRectValue];
    CGFloat height = keyboardFrame.size.height;

    [UIView animateWithDuration:animationDuration animations:^{
        self.keyboardHeight.constant = -height;
        [self.view setNeedsLayout];
    }];
}

Le truc, c'est que le bloc d'animation est instantané et je vois un espace blanc apparaître avant que le clavier ait terminé son animation. Donc, fondamentalement, je vois le fond blanc de la vue pendant que le clavier s'anime. Je ne peux pas faire durer l'animation aussi longtemps que le clavier s'anime.

Suis-je en train de l'aborder de la mauvaise façon? Merci d'avance!

34
Marty W

Essayez-le de cette façon:

self.keyboardHeight.constant = -height;
[self.view setNeedsUpdateConstraints];

[UIView animateWithDuration:animationDuration animations:^{
   [self.view layoutIfNeeded];
}];

N'oubliez pas ce modèle car cela devrait être la bonne façon de mettre à jour les dispositions basées sur des contraintes (selon WWDC). Vous pouvez également ajouter ou supprimer NSLayoutConstraints tant que vous appelez setNeedsUpdateConstraints après.

52
John Estropia

Si vous utilisez UITableViewController, la taille du clavier doit être automatiquement prise en charge par iOS pour ajuster les contentInsets. Mais si votre tableView est à l'intérieur d'un UIViewController, vous vouliez probablement utiliser ceci:

KeyboardLayoutConstraint dans le framework Spring . La solution la plus simple que j'ai trouvée jusqu'à présent. KeyboardLayoutConstraint

14
James Tang

Essayez le code suivant. Dans ce cas, la vue tabulaire est affichée en bas de l'écran.

- (void)keyboardWillShow:(NSNotification *)notification { // UIKeyboardWillShowNotification

    NSDictionary *info = [notification userInfo];
    NSValue *keyboardFrameValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [keyboardFrameValue CGRectValue];

    BOOL isPortrait = UIDeviceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
    CGFloat keyboardHeight = isPortrait ? keyboardFrame.size.height : keyboardFrame.size.width;

    // constrBottom is a constraint defining distance between bottom Edge of tableView and bottom Edge of its superview
    constrBottom.constant = keyboardHeight; 
    // or constrBottom.constant = -keyboardHeight - in case if you create constrBottom in code (NSLayoutConstraint constraintWithItem:...:toItem:...) and set views in inverted order

    [UIView animateWithDuration:animationDuration animations:^{
        [tableView layoutIfNeeded];
    }];
}


- (void)keyboardWillHide:(NSNotification *)notification { // UIKeyboardWillHideNotification

    NSDictionary *info = [notification userInfo];
    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    constrBottom.constant = 0;
    [UIView animateWithDuration:animationDuration animations:^{
        [tableView layoutIfNeeded];
    }];
}
8
Grigori A.

L'approche que j'ai prise est d'ajouter une vue qui suit la taille du clavier. Ajoutez-le en dessous de votre vue de table, ou de la saisie de texte ou autre et il poussera les choses vers le haut lorsque le clavier apparaîtra.

Voici comment j'ai configuré la hiérarchie des vues:

NSDictionary *views = @{@"chats": self.chatsListView, @"reply": self.replyBarView, @"fakeKeyboard":self.fakeKeyboardView};
[self.view addVisualConstraints:@"V:|-30-[chats][reply][fakeKeyboard]|" views:views];

Et puis les bits clés de la vue suivant la taille du clavier ressemblent à ceci:

- (void)keyboardWillShow:(NSNotification *)notification
{
    // Save the height of keyboard and animation duration
    NSDictionary *userInfo = [notification userInfo];
    CGRect keyboardRect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    self.desiredHeight = CGRectGetHeight(keyboardRect);
    self.duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];

    [self animateSizeChange];
}

- (void)keyboardWillHide:(NSNotification *)notification
{
    self.desiredHeight = 0.0f;

    [self animateSizeChange];
}

- (CGSize)intrinsicContentSize
{
    return CGSizeMake(UIViewNoIntrinsicMetric, self.desiredHeight);
}

- (void)animateSizeChange
{
    [self invalidateIntrinsicContentSize];

    // Animate transition
    [UIView animateWithDuration:self.duration animations:^{
        [self.superview layoutIfNeeded];
    }];
}

La bonne chose à propos de laisser cette vue particulière gérer son redimensionnement est que vous pouvez laisser le contrôleur de vue l'ignorer, et vous pouvez également réutiliser cette vue n'importe où dans votre application où vous souhaitez tout déplacer.

Le fichier complet est ici: https://Gist.github.com/shepting/6025439

2
Steven Hepting