Anthony Mills Anthony Mills - 3 months ago 26
iOS Question

How do I keep the keyboard from covering my UI instead of resizing it?

In iOS, Xamarin.Forms resizes the screen when the keyboard comes up when the root node is a

. But when the root node is not a
the keyboard hides part of the UI. How do you keep this from happening?


The way to fix this is with a custom renderer that listens for the keyboard showing up and adds padding while it's there.

In your PCL project, KeyboardResizingAwareContentPage.cs:

using Xamarin.Forms;

public class KeyboardResizingAwareContentPage : ContentPage {
    public bool CancelsTouchesInView = true;

In your iOS project, IosKeyboardFixPageRenderer.cs:

using Foundation;
using MyProject.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(KeyboardResizingAwareContentPage), typeof(IosKeyboardFixPageRenderer))]

namespace MyProject.iOS.Renderers {
    public class IosKeyboardFixPageRenderer : PageRenderer {
        NSObject observerHideKeyboard;
        NSObject observerShowKeyboard;

        public override void ViewDidLoad()

            var cp = Element as KeyboardResizingAwareContentPage;
            if (cp != null && !cp.CancelsTouchesInView) {
                foreach (var g in View.GestureRecognizers) {
                    g.CancelsTouchesInView = false;

        public override void ViewWillAppear(bool animated)

            observerHideKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillHideNotification, OnKeyboardNotification);
            observerShowKeyboard = NSNotificationCenter.DefaultCenter.AddObserver(UIKeyboard.WillShowNotification, OnKeyboardNotification);

        public override void ViewWillDisappear(bool animated)


        void OnKeyboardNotification(NSNotification notification)
            if (!IsViewLoaded) return;

            var frameBegin = UIKeyboard.FrameBeginFromNotification(notification);
            var frameEnd = UIKeyboard.FrameEndFromNotification(notification);

            var page = Element as ContentPage;
            if (page != null && !(page.Content is ScrollView)) {
                var padding = page.Padding;
                page.Padding = new Thickness(padding.Left, padding.Top, padding.Right, padding.Bottom + frameBegin.Top - frameEnd.Top);