Autolayout Constraint - Keyboard

后端 未结 4 1168
迷失自我
迷失自我 2020-12-22 19:05

Im stuck trying to animate a table view smoothly which has an autolayout contraint. I have a reference to the constraint \"keyboardHeight\" in my .h and have linked this up

相关标签:
4条回答
  • 2020-12-22 19:25

    Try the next code. In this case table view lays out at the bottom edge of the screen.

    - (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];
        }];
    }
    
    0 讨论(0)
  • 2020-12-22 19:26

    Try it this way:

    self.keyboardHeight.constant = -height;
    [self.view setNeedsUpdateConstraints];
    
    [UIView animateWithDuration:animationDuration animations:^{
       [self.view layoutIfNeeded];
    }];
    

    Remember this pattern because this should be the correct way to update constraint-based layouts (according to WWDC). You can also add or remove NSLayoutConstraints as long as you call setNeedsUpdateConstraints after.

    0 讨论(0)
  • 2020-12-22 19:33

    If you're using UITableViewController, keyboard size should be automatically accommodated by iOS to adjust the contentInsets. But if your tableView is inside a UIViewController, you probably wanted to use this:

    KeyboardLayoutConstraint in the Spring framework. Simplest solution I've found so far. KeyboardLayoutConstraint

    0 讨论(0)
  • 2020-12-22 19:43

    The approach I took is to add a view which follows the size of the keyboard. Add it below your tableview, or text input or whatever and it will push things up when the keyboard appears.

    This is how I set up the view hierarchy:

    NSDictionary *views = @{@"chats": self.chatsListView, @"reply": self.replyBarView, @"fakeKeyboard":self.fakeKeyboardView};
    [self.view addVisualConstraints:@"V:|-30-[chats][reply][fakeKeyboard]|" views:views];
    

    And then the key bits of the keyboard-size-following view look like this:

    - (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];
        }];
    }
    

    The nice thing about letting this particular view handle its resizing is that you can let the view controller ignore it, and you can also re-use this view any place in your app you want to shift everything up.

    The full file is here: https://gist.github.com/shepting/6025439

    0 讨论(0)
提交回复
热议问题