我试图平滑地制作具有自动布局约束力的桌面视图。我在我的.h中引用了约束“keyboardHeight”,并在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];
}];
}
事情是动画块是瞬时的,我看到在键盘完成动画之前出现了空格。所以基本上我看到视图的白色背景,因为键盘是动画。只要键盘是动画,我就无法使动画持续。
我接近这个错误的方式吗?提前谢谢!
答案 0 :(得分:52)
以这种方式尝试:
self.keyboardHeight.constant = -height;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
请记住这种模式,因为这应该是更新基于约束的布局的正确方法(根据WWDC)。只要您之后拨打NSLayoutConstraint
,您也可以添加或删除setNeedsUpdateConstraints
。
答案 1 :(得分:14)
如果您正在使用UITableViewController,iOS应自动调整键盘大小以调整contentInsets。但是如果你的tableView在UIViewController中,你可能想要使用它:
KeyboardLayoutConstraint框架中的Spring。到目前为止我找到的最简单的解决方案。
答案 2 :(得分:8)
尝试下一个代码。在这种情况下,表格视图位于屏幕的底部边缘。
- (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];
}];
}
答案 3 :(得分:2)
我采取的方法是添加一个遵循键盘大小的视图。将它添加到您的桌面视图下方,或文本输入或其他任何内容,当键盘出现时它会向上推。
这是我设置视图层次结构的方式:
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];
}];
}
让这个特定视图处理其大小调整的好处是你可以让视图控制器忽略它,你也可以在应用程序的任何地方重新使用这个视图,你想要将所有内容都移除。