Ograniczenie Autolayout-Klawiatura

Utknąłem próbując płynnie animować widok tabeli z kontrastem autolayout. Mam odniesienie do ograniczenia "keyboardHeight" w moim .h i powiązali to w IB. Wszystko, co chcę zrobić, to animować widok tabeli za pomocą klawiatury, gdy pojawi się. Oto Mój kod:

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

Rzecz w tym, że blok animacji jest natychmiastowy i widzę, że białe spacje pojawiają się przed zakończeniem animacji na klawiaturze. Więc w zasadzie widzę białe tło widoku jak klawiatura jest animuję. Animacja nie może trwać tak długo, jak animowana jest klawiatura.

Czy podchodzę do tego w złą stronę? Z góry dzięki!
Author: Stavash, 2012-10-17

4 answers

Spróbuj w ten sposób:

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

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

Zapamiętaj ten wzorzec, ponieważ powinien to być właściwy sposób aktualizacji układów opartych na ograniczeniach (zgodnie z WWDC). Możesz również dodawać lub usuwać NSLayoutConstraint s, o ile wywołasz setNeedsUpdateConstraints po.

 52
Author: John Estropia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-17 00:58:02

Jeśli używasz UITableViewController, rozmiar klawiatury powinien być automatycznie dostosowywany przez iOS, aby dostosować zawartość zestawów. Ale jeśli tableView znajduje się wewnątrz kontrolera UIViewController, prawdopodobnie chciałeś użyć tego:

KeyboardLayoutConstraint w frameworku Spring . Najprostsze rozwiązanie, jakie do tej pory znalazłem. KeyboardLayoutConstraint

 13
Author: James Tang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-01 17:08:10

Spróbuj następnego kodu. W tym przypadku Widok tabeli znajduje się na dolnej krawędzi ekranu.

- (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
Author: Grigori A.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-21 15:53:25

Moje podejście polega na dodaniu widoku zgodnego z rozmiarem klawiatury. Dodaj go poniżej widoku tableview lub wprowadzania tekstu lub cokolwiek, a to popchnie rzeczy, gdy pojawi się klawiatura.

Tak ustawiłem hierarchię widoków:

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

I wtedy bity klawiszy w widoku keyboard-size-following wyglądają tak:

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

Fajną rzeczą w pozwalaniu temu konkretnemu widokowi obsługiwać jego zmianę rozmiaru jest to, że możesz pozwolić, aby kontroler widoku go zignorował, a także możesz ponownie użyj tego widoku w dowolnym miejscu w aplikacji, w którym chcesz przesunąć wszystko w górę.

Pełny plik znajduje się tutaj: https://gist.github.com/shepting/6025439

 1
Author: Steven Hepting,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-18 18:36:56