zic10
zic10

Reputation: 2330

UIView programatic constraint height increase when keyboard present

I'm building a comment input control for an app. This control consists of a UITextView embedded in a UIView. All constraints are being handled programatically. What happens is when the user taps the UITextView, the keyboard will open. This calls the keyboard observer methods and I then adjust the bottom constraint for the comment input control to move up with the keyboard. However, I am also trying to increase the height of the input control at the same time so the user has more room to type. I'm having trouble achieving this.

-(void)updateViewConstraints
{

  NSDictionary *views = @{
                          @"table"           : self.commentsTableView,
                          @"seeMoreComments" : self.seeMoreCommentsView,
                          @"commentInput"    : self.commentEntryInput
                          };

  //See More Comments Constraints
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[seeMoreComments]-0-|" options:0 metrics:nil views:views]];
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[seeMoreComments(45)]" options:0 metrics:nil views:views]];

  //Table view constraints
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[table]-0-|" options:0 metrics:nil views:views]];
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[seeMoreComments]-0-[table]-0-|" options:0 metrics:nil views:views]];

  //Comment entry input
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[commentInput]-0-|" options:0 metrics:nil views:views]];

  commentInputVerticalConstraint = [NSLayoutConstraint constraintWithItem:self.commentEntryInput
                                                                attribute:NSLayoutAttributeHeight
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:nil
                                                                attribute:NSLayoutAttributeHeight
                                                               multiplier:1.0
                                                                 constant:commentInputHeight];

  if(commentInputBottomConstraint == nil)
  {
    commentInputBottomConstraint =
    [NSLayoutConstraint constraintWithItem:self.commentEntryInput
                                 attribute:NSLayoutAttributeBottom
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.view
                                 attribute:NSLayoutAttributeBottom multiplier:1.0
                                  constant:0.0];

  }

  [self.view addConstraint:commentInputVerticalConstraint];
  [self.view addConstraint:commentInputBottomConstraint];

  [super updateViewConstraints];
}

Now I have a method that is called when keyBoardWillShow is called. This method animates the comment input control up when the keyboard appears.

    (void)animateContentWithKeyboardInfo:(NSDictionary *)keyboardInfo
    {
      NSNumber                *animationDuration  = keyboardInfo[ UIKeyboardAnimationDurationUserInfoKey ];
      NSValue                 *keyboardFrameValue = keyboardInfo[ UIKeyboardFrameEndUserInfoKey ];
      CGRect                  keyboardFrame       = [keyboardFrameValue CGRectValue];
      UIViewAnimationCurve    animationCurve      = [keyboardInfo[ UIKeyboardAnimationCurveUserInfoKey ] intValue];

      UIViewAnimationOptions  animationOptions    = animationOptionWithCurve(animationCurve);

      commentInputBottomConstraint.constant = (keyboardFrame.origin.y - [UIScreen mainScreen].bounds.size.height);

      //Increase the veritcal height of the comment input control
      commentInputVerticalConstraint.constant = 125;

      //Takes into account that the Tab Bar is 50 points, and adjust for this
      //value.

      if(keyboardAppeared == YES)
      {
        commentInputBottomConstraint.constant += TAB_BAR_OFFSET;
      }

      else
      {
        commentInputBottomConstraint.constant -= TAB_BAR_OFFSET;
      }

      [self.view layoutIfNeeded];

      [self.view setNeedsUpdateConstraints];

      [UIView animateWithDuration:[animationDuration floatValue] delay:0.0 options:animationOptions animations:
       ^{


        [self.view layoutIfNeeded];

       } completion:nil];
    }

However, when I try to adjust the constant of the of the commentInputVerticalConstraint I receive this error message:

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:0x1899fcb0 V:[CommentEntryInput:0x176e5160(50)]>",
    "<NSLayoutConstraint:0x1899e5c0 V:[CommentEntryInput:0x176e5160(125)]>"
)

I'm not sure if there is a way for me to "reset" or adjust the constraint to handle when the keyboard appears and then put it back to normal when the keyboard disappears. Any help would be appreciated.

Upvotes: 0

Views: 202

Answers (1)

Henry T Kirk
Henry T Kirk

Reputation: 961

Your problem is that -(void)updateViewConstraints is getting called more than once. So you are creating a new constraint and adding it to the view twice. Try checking if the constraint is nil or not.

I also don't think you need the first [self.view layoutIfNeeded] before the animation change of the constant. When changing constant, just set it then wrap the [self.view layoutIfNeeded] in a animation block to animate to that new value.

Upvotes: 1

Related Questions