Reputation: 1067
So, much like the Messages app, I have a UITableView that takes up most of the screen. Below the UITableView, I have a UIView that contains a UITextView and a UIButton. When the user clicks on the UITextView, the keyboard appears. I have successfully moved the UIView to the top of the keyboard (that is what my bottomConstraint outlet does), but I am struggling to move the UITableView as well.
Right now I have a height constraint on the UITableView that is set to 528. I have connected that constraint to an Outlet and here is my keyboardWillShow method.
- (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];
}];}
Here are screenshots of my constraints/storyboard.
^^view controller
^^UITableView Constraints
^^UIView Constraints (View containing button + textview)
Here is my error:
Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property 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)]>"
)
Will attempt to recover by breaking constraint
NSLayoutConstraint:0x174280320 V:[UITableView:0x135031c00(528)]
Upvotes: 1
Views: 1048
Reputation: 1182
Something like this should work as you just need to set the height don't need to calculate new frames:
- (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];
}];}
Also it seems like would be easier if you just set the bottom constraint of the tableView to be the top of the composeTextView instead of use a fixed height. that would work all the time.
Upvotes: 2