0

Is there a graceful way of getting the frame (size) of whatever inputView is currently visible? By graceful, I mean not resigning, then re-activating the first responder, since that discards any kbd state data, e.g. Shift key status.

What I currently do is this:

- (CGSize)inputViewSize
{
    __block CGSize result = CGSizeZero;
    UIResponder *firstResponder = [self getFirstResponder];
    id observer = [NSNotificationCenter.defaultCenter addObserverForName:UIKeyboardDidShowNotification object:nil queue:nil usingBlock:^(NSNotification *note)
    {
        result = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    }];
    [firstResponder resignFirstResponder];
    [firstResponder becomeFirstResponder];
    [NSNotificationCenter.defaultCenter removeObserver:observer];
    return result;
}

EDIT: What I should have been doing is this:

@implementation UIApplication (KeyboardFrame)

static CGRect _keyboardFrame = (CGRect){ (CGPoint){ 0.0f, 0.0f }, (CGSize) { 0.0f, 0.0f } };
+ (CGSize)keyboardSize { return _keyboardFrame.size; }

+ (void)load
{
    [NSNotificationCenter.defaultCenter addObserverForName:UIKeyboardDidShowNotification object:nil queue:nil usingBlock:^(NSNotification *note)
    {
        _keyboardFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    }];
    [NSNotificationCenter.defaultCenter addObserverForName:UIKeyboardDidChangeFrameNotification object:nil queue:nil usingBlock:^(NSNotification *note)
    {
        _keyboardFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    }];
    [NSNotificationCenter.defaultCenter addObserverForName:UIKeyboardDidHideNotification object:nil queue:nil usingBlock:^(NSNotification *note)
    {
        _keyboardFrame = CGRectZero;
    }];
}

@end

1 Answers1

0

You need to observe keyboard notifications. You can leverage the following two notifications if keyboard frame changes are of interest:

UIKeyboardWillChangeFrameNotification 
UIKeyboardDidChangeFrameNotification 
Joe Smith
  • 1,900
  • 1
  • 16
  • 15
  • These do not trigger any more than `UIKeyboardDidShowNotification`, unless `firstResponder` is first resigned, then re-activated, which is what I hope to avoid here. – Antti Hautaniemi May 12 '15 at 17:22
  • I just tested. These notifications work for me somehow. – Joe Smith May 13 '15 at 02:59
  • Please elaborate in code. Just to remind you, future keyboard frame changes are of no interest to me (and I know how to do that), only the existing frame at the time of invocation. – Antti Hautaniemi May 13 '15 at 04:19
  • Let me clarify. I am not aware of any API to check the keyboard frame size. What we can do is observing the keyboard show/hide/frame changes and save the size in a variable whenever it changes. This way we always know the keyboard frame size. Hope this is clear. – Joe Smith May 13 '15 at 05:11
  • Actually, having some static code listening on these notifications for the lifetime of the app really is the easiest solution. This allows me to query the kbd size gracefully whenever needed. I edited a solution to the original post. – Antti Hautaniemi May 13 '15 at 17:49
  • I am not sure your updated solution would be adequate. The frame size of the keyboard may change while the keyboard is displayed. In other words, the frame size may change without involving hiding/showing the keyboard. Disregard this comment if it doesn't concern you. – Joe Smith May 13 '15 at 18:00
  • You're probably right. I added a listener for that case as well. – Antti Hautaniemi May 14 '15 at 07:03