Ограничение автоопределения - Клавиатура
Я застрял, пытаясь анимировать табличный вид гладко, у которого есть автоопределение. У меня есть ссылка на ограничение "keyboardHeight" в моем .h и связали это с IB. Все, что я хочу сделать, - это оживить табличный вид с клавиатурой, когда она появится. Вот мой код:
- (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];
}];
}
Дело в том, что блок анимации мгновен, и я вижу, что пробел появляется до того, как клавиатура закончила свою анимацию. Поэтому в основном я вижу белый фон представления, когда клавиатура оживляет. Я не могу сделать анимацию последней до тех пор, пока клавиатура оживляет.
Я подхожу к этому неправильно? Спасибо заранее!
Ответы
Ответ 1
Попробуйте так:
self.keyboardHeight.constant = -height;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
Помните этот шаблон, потому что это должен быть правильный способ обновления макетов на основе ограничений (согласно WWDC). Вы также можете добавить или удалить NSLayoutConstraint
, пока вы вызываете setNeedsUpdateConstraints
после.
Ответ 2
Если вы используете UITableViewController, размер клавиатуры должен автоматически устанавливаться iOS для настройки содержимогоInsets. Но если ваш tableView находится внутри UIViewController, вы, вероятно, захотите использовать это:
KeyboardLayoutConstraint в Spring framework, Самое простое решение, которое я нашел до сих пор.
Ответ 3
Попробуйте следующий код. В этом случае табличный вид располагается в нижнем краю экрана.
- (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];
}];
}
Ответ 4
Подход, который я принял, - это добавить представление, которое следует за размером клавиатуры. Добавьте его под своим табличным представлением или текстовым вводом или что-то еще, и оно подтолкнет вас, когда появится клавиатура.
Вот как я установил иерархию представлений:
NSDictionary *views = @{@"chats": self.chatsListView, @"reply": self.replyBarView, @"fakeKeyboard":self.fakeKeyboardView};
[self.view addVisualConstraints:@"V:|-30-[chats][reply][fakeKeyboard]|" views:views];
И тогда ключевые биты представления размера клавиатуры выглядят следующим образом:
- (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];
}];
}
Самое приятное в том, что позволить этому конкретному виду обработать его изменение размера - это то, что вы можете позволить контроллеру представления игнорировать его, и вы также можете повторно использовать это представление в любом месте приложения, которое хотите переместить все.
Полный файл находится здесь:
https://gist.github.com/shepting/6025439