notificationsxamarin.iosuikeyboardeventargs

UIKeyboardEventArgs FrameBegin Height returns 0 after first click


I have a bit of code where I'm scrolling the view up if the textbox is covered by the keyboard. I'm using the method style as shown in the 'UIKeyboard.Notifications.ObserveWillShow' example in Xamarin's developer guide where the callback method is 'KeyboardWillShow'. Here's my implementation.

public void KeyboardWillShow(UIKeyboardEventArgs KeyboardArgs, UIView uiResponderView)
    {
    if (ScrollView != null)
            {
                if (uiResponderView != null)
                {
                    UIEdgeInsets contentInsets = new UIEdgeInsets(0.0f, 0.0f, KeyboardArgs.FrameBegin.Height, 0.0f);
                    ScrollView.ContentInset = contentInsets;
                    ScrollView.ScrollIndicatorInsets = contentInsets;

                    CGRect tableViewRect = ScrollView.Frame;
                    tableViewRect.Height -= KeyboardArgs.FrameBegin.Height;

                    if (!tableViewRect.Contains(uiResponderView.Frame.Location))
                    {
                        ScrollView.ScrollRectToVisible(uiResponderView.Frame, true);
                    }
                }
            }
    }

I'm also listening for when the keyboard hides using the 'UIKeyboard.Notifications.ObserveWillHide' example in Xamarin's developer guide where the callback method is 'KeyboardWillHide'. Here's my implementation of it.

public void KeyBoardWillHide(object sender, UIKeyboardEventArgs args)
    {
        ScrollView.ContentInset = UIEdgeInsets.Zero;
        ScrollView.ScrollIndicatorInsets = UIEdgeInsets.Zero;
    }

All of this works the first time with no issue, but every subsequent time the "KeyboardArgs.FrameBegin.Height" returns 0. Could someone please let me know what I'm missing?

EDIT: I should also note that on "ViewWillDisappear", I dispose of the observers.

SOLUTION: Based on Kevin's notes, I changed my 'KeyboardWillShow' event to use 'KeyboardArgs.FrameEnd.Height' instead of 'KeyboardArgs.FrameBegin.Height' and the process works without issue. The event now looks like:

public void KeyboardWillShow(UIKeyboardEventArgs KeyboardArgs, UIView uiResponderView)
{
    if (ScrollView != null)
    {
        if (uiResponderView != null)
        {
            UIEdgeInsets contentInsets = new UIEdgeInsets(0.0f, 0.0f, KeyboardArgs.FrameEnd.Height, 0.0f);
            ScrollView.ContentInset = contentInsets;
            ScrollView.ScrollIndicatorInsets = contentInsets;

            CGRect tableViewRect = ScrollView.Frame;
            tableViewRect.Height -= KeyboardArgs.FrameEnd.Height;

            if (!tableViewRect.Contains(uiResponderView.Frame.Location))
            {
                ScrollView.ScrollRectToVisible(uiResponderView.Frame, true);
            }
        }
    }
}

Solution

  • Solution:

    Use FrameEnd.Height instead of FrameBegin.Height.

    References:

    UIKeyboardFrameBeginUserInfoKey

    The key for an NSValue object containing a CGRect that identifies the starting frame rectangle of the keyboard in screen coordinates. The frame rectangle reflects the current orientation of the device.

    UIKeyboardFrameEndUserInfoKey

    The key for an NSValue object containing a CGRect that identifies the ending frame rectangle of the keyboard in screen coordinates. The frame rectangle reflects the current orientation of the device.

    Apple's Documentations: https://developer.apple.com/documentation/uikit/uikeyboardframebeginuserinfokey https://developer.apple.com/documentation/uikit/uikeyboardframeenduserinfokey

    Other related case: iOS 11 - Keyboard Height is returning 0 in keyboard notification