6

I'm trying to keep a text field sitting atop the keyboard in iOS 8. But when a user swipes up or down the top of the keyboard to show or dismiss iOS 8 word suggestions, I need to a notification of the new height of the keyboard so I can move my text field up or down by that height.

How can I accomplish this?

Thanks!

Juan Boero
  • 6,281
  • 1
  • 44
  • 62
Tony Friz
  • 883
  • 1
  • 10
  • 27
  • Actually, keyboard will show notification does have the correct height but not at the correct time. So when the suggestions box is not visible it'll show 271.00 on my 6+ and 236.00 when suggestions are visible. – Tony Friz May 02 '15 at 02:30

3 Answers3

10

You can register for UIKeyboardDidShowNotification and then get the keyboard frame from the notification with UIKeyboardFrameEndUserInfoKey.

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(handleKeyboardDidShowNotification:) 
                                             name:UIKeyboardDidShowNotification 
                                           object:nil];


- (void)handleKeyboardDidShowNotification:(NSNotification *)notification
{
    NSDictionary* info = [notification userInfo];
    CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    // Move your textview into view here
}

This notification will be sent even in the event that the keyboard is already showing and is just going to change size, so you'll get it whenever you swipe up or down on the top of the keyboard.

charmingToad
  • 1,597
  • 11
  • 18
2

Here's some code from a custom inputView I built. It even handles the animation curve for your custom view so that it matches the velocity of the keyboard and moves along with it.

The notification will fire when suggestions are shown/hidden.

- (void)registerForKeyboardNotifications {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification object:nil]; }

- (void)keyboardWillShow:(NSNotification *)notification {
    NSDictionary* info = [notification userInfo];
    NSNumber *duration = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [info objectForKey: UIKeyboardAnimationCurveUserInfoKey];
    CGSize endKbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    CGRect baseFrame = self.frame;
    baseFrame.origin.y = CGRectGetMaxY(self.frame) - (endKbSize.height - 5);

    [UIView animateWithDuration:duration.floatValue delay:0.0f options:curve.integerValue animations:^{
        self.frame = baseFrame;
    } completion:^(BOOL finished) {
        self.frame = baseFrame;
    }]; }

- (void)keyboardWillHide:(NSNotification *)notification {

    NSDictionary* info = [notification userInfo];
    NSNumber *duration = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [info objectForKey: UIKeyboardAnimationCurveUserInfoKey];

    [UIView animateWithDuration:duration.floatValue delay:0.0f options:curve.integerValue animations:^{
        self.frame = _originalRect;
    } completion:nil]; 
}
Beau Nouvelle
  • 6,962
  • 3
  • 39
  • 54
0

Swift 4 Solution:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    registerKeyboardNotifications()
}

func registerKeyboardNotifications() {
    NotificationCenter.default.addObserver(self,
                                         selector: #selector(keyboardWillShow(notification:)),
                                         name: NSNotification.Name.UIKeyboardWillShow,
                                         object: nil)
    NotificationCenter.default.addObserver(self,
                                         selector: #selector(keyboardWillHide(notification:)),
                                         name: NSNotification.Name.UIKeyboardWillHide,
                                         object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo! as NSDictionary
    let keyboardInfo = userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue
    let keyboardSize = keyboardInfo.cgRectValue.size
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    scrollView.contentInset = contentInsets
    scrollView.scrollIndicatorInsets = contentInsets
}

@objc func keyboardWillHide(notification: NSNotification) {
    scrollView.contentInset = .zero
    scrollView.scrollIndicatorInsets = .zero
}