使用自动布局出现键盘时无法更改 UITableView 高度约束
Unable to change UITableView Height Constraint When Keyboard Appears Using Autolayout
因此,与消息应用程序非常相似,我有一个占据大部分屏幕的 UITableView。在 UITableView 下方,我有一个包含 UITextView 和 UIButton 的 UIView。当用户点击 UITextView 时,键盘出现。我已经成功地将 UIView 移动到键盘的顶部(这就是我的 bottomConstraint 插座所做的),但我也在努力移动 UITableView 。
现在我在 UITableView 上设置了一个高度限制,它设置为 528。我已经将该限制连接到一个 Outlet,这是我的 keyboardWillShow 方法。
- (void)keyboardWillShow:(NSNotification *)sender {
NSDictionary *info = [sender userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect newFrame = [self.view convertRect:frame fromView:[[UIApplication sharedApplication] delegate].window];
self.bottomConstraint.constant = newFrame.origin.y - CGRectGetHeight(self.view.frame);
CGFloat height = CGRectGetHeight(self.view.frame) - self.composeTextView.frame.size.height - newFrame.origin.y;
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];}
这是我的 constraints/storyboard 的屏幕截图。
^^视图控制器
^^UITableView 约束
^^UIView Constraints (View containing button + textview)
这是我的错误:
无法同时满足约束条件。
可能至少以下列表中的约束之一是您不想要的。试试这个:(1)查看每个约束并尝试找出您不期望的; (2) 找到添加了不需要的约束或约束的代码并修复它。 (注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档)
(
"<NSLayoutConstraint:0x174280320 V:[UITableView:0x135031c00(528)]>",
"<NSLayoutConstraint:0x17409ff40 V:[UIView:0x174184ac0(40)]>",
"<NSLayoutConstraint:0x1742807d0 V:|-(0)-[UITableView:0x135031c00] (Names: '|':UIView:0x174184b90 )>",
"<NSLayoutConstraint:0x1742808c0 V:[UITableView:0x135031c00]-(0)-[UIView:0x174184ac0]>",
"<_UILayoutSupportConstraint:0x1740b9d40 V:[_UILayoutGuide:0x1741b3b00(0)]>",
"<_UILayoutSupportConstraint:0x1740b9ce0 _UILayoutGuide:0x1741b3b00.bottom == UIView:0x174184b90.bottom>",
"<NSLayoutConstraint:0x174280690 UIView:0x174184ac0.bottom == _UILayoutGuide:0x1741b3b00.top - 224>",
"<NSLayoutConstraint:0x174280dc0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x174184b90(568)]>"
)
将尝试通过打破约束来恢复
NSLayoutConstraint:0x174280320 V:[UITableView:0x135031c00(528)]
像这样的东西应该可以工作,因为你只需要设置高度而不需要计算新的帧:
- (void)keyboardWillShow:(NSNotification *)sender {
NSDictionary *info = [sender userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat height = self.tableViewHeightConstraint.constant-keyboardFrame.size.height-self.composeTextView.frame.size.height;
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];}
另外,如果您只是将 tableView 的底部约束设置为 composeTextView 的顶部而不是使用固定高度,这似乎会更容易。那会一直有效。
因此,与消息应用程序非常相似,我有一个占据大部分屏幕的 UITableView。在 UITableView 下方,我有一个包含 UITextView 和 UIButton 的 UIView。当用户点击 UITextView 时,键盘出现。我已经成功地将 UIView 移动到键盘的顶部(这就是我的 bottomConstraint 插座所做的),但我也在努力移动 UITableView 。
现在我在 UITableView 上设置了一个高度限制,它设置为 528。我已经将该限制连接到一个 Outlet,这是我的 keyboardWillShow 方法。
- (void)keyboardWillShow:(NSNotification *)sender {
NSDictionary *info = [sender userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect newFrame = [self.view convertRect:frame fromView:[[UIApplication sharedApplication] delegate].window];
self.bottomConstraint.constant = newFrame.origin.y - CGRectGetHeight(self.view.frame);
CGFloat height = CGRectGetHeight(self.view.frame) - self.composeTextView.frame.size.height - newFrame.origin.y;
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];}
这是我的 constraints/storyboard 的屏幕截图。
^^视图控制器
^^UITableView 约束
^^UIView Constraints (View containing button + textview)
这是我的错误:
无法同时满足约束条件。 可能至少以下列表中的约束之一是您不想要的。试试这个:(1)查看每个约束并尝试找出您不期望的; (2) 找到添加了不需要的约束或约束的代码并修复它。 (注意:如果您看到不理解的 NSAutoresizingMaskLayoutConstraints,请参阅 UIView 属性 translatesAutoresizingMaskIntoConstraints 的文档) (
"<NSLayoutConstraint:0x174280320 V:[UITableView:0x135031c00(528)]>",
"<NSLayoutConstraint:0x17409ff40 V:[UIView:0x174184ac0(40)]>",
"<NSLayoutConstraint:0x1742807d0 V:|-(0)-[UITableView:0x135031c00] (Names: '|':UIView:0x174184b90 )>",
"<NSLayoutConstraint:0x1742808c0 V:[UITableView:0x135031c00]-(0)-[UIView:0x174184ac0]>",
"<_UILayoutSupportConstraint:0x1740b9d40 V:[_UILayoutGuide:0x1741b3b00(0)]>",
"<_UILayoutSupportConstraint:0x1740b9ce0 _UILayoutGuide:0x1741b3b00.bottom == UIView:0x174184b90.bottom>",
"<NSLayoutConstraint:0x174280690 UIView:0x174184ac0.bottom == _UILayoutGuide:0x1741b3b00.top - 224>",
"<NSLayoutConstraint:0x174280dc0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x174184b90(568)]>"
)
将尝试通过打破约束来恢复
NSLayoutConstraint:0x174280320 V:[UITableView:0x135031c00(528)]
像这样的东西应该可以工作,因为你只需要设置高度而不需要计算新的帧:
- (void)keyboardWillShow:(NSNotification *)sender {
NSDictionary *info = [sender userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat height = self.tableViewHeightConstraint.constant-keyboardFrame.size.height-self.composeTextView.frame.size.height;
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];}
另外,如果您只是将 tableView 的底部约束设置为 composeTextView 的顶部而不是使用固定高度,这似乎会更容易。那会一直有效。