Skip to content Skip to sidebar Skip to footer

Xamarin Webview With Form Scrolls Out Of View When Clicking Textbox

Using a webview to load a simple html form, the form displays ok. When clicking an input field the entire form disappears showing arrows up and down and done button at bottom part

Solution 1:

Odd, so I made a web page using your HTML code, and then created a new Xamarin.Forms solution with a WebView pointing to the page I created from your HTML. When I clicked any of the input fields the soft keyboard showed as expected. However if I made sure the WebView was at the bottom of the screen, under where the keyboard shows, the keyboard does hide the WebView. To fix this, you would need a custom page renderer [1] to scroll the view up when the keyboard shows up and scroll the view back down when the keyboard goes away.

Here is some sample code to do this. I assume you would only want to do this on pages that have that WebView, so first in the Forms PCL project create an empty subclass of ContentPage called WebViewContentPage:

public class WebViewContentPage : ContentPage {}

Then you inherit from the WebViewContentPage for the actual page that has the WebView, in my test I called it TestWebInputPage:

public partial class TestWebInputPage : WebViewContentPage
{ 
    public TestWebInputPage()
    {
        InitializeComponent();
    }
}

My Xaml is (change UrlToWebPageHere to the actual url of your web page):

<?xml version="1.0" encoding="utf-8"?>
<local:WebViewContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:TestWebInput" x:Class="TestWebInput.TestWebInputPage">
    <StackLayout>
        <Label 
            Text="Take up space" 
            HeightRequest="400" />
        <WebView 
            x:Name="webView" 
            Navigating="Handle_Navigating" 
            Source="UrlToWebPageHere" 
            VerticalOptions="FillAndExpand" />
    </StackLayout>
</local:WebViewContentPage>

And finally the custom page renderer code. This goes in the iOS app project:

using System;
using Xamarin.Forms;
using TestWebInput.iOS;
using Xamarin.Forms.Platform.iOS;
using Foundation;
using UIKit;
using TestWebInput;

[assembly: ExportRenderer(typeof(WebViewContentPage), typeof(ContentPageRenderer))]
namespace TestWebInput.iOS
{
    public class ContentPageRenderer : PageRenderer
    {   
        private NSObject keyBoardWillShow;
        private NSObject keyBoardWillHide;
        private nfloat scrollAmout;
        private double animDuration;
        private UIViewAnimationCurve animCurve;
        private bool keyboardShowing;

        public override void ViewDidLoad()
        {

            base.ViewDidLoad();

            keyBoardWillShow = UIKeyboard.Notifications.ObserveWillShow(KeyboardWillShow);

            keyBoardWillHide = UIKeyboard.Notifications.ObserveWillHide(KeyboardWillHide);
        }

        void KeyboardWillShow(object sender, UIKeyboardEventArgs args)
        {
            if (!keyboardShowing)
            {
                keyboardShowing = true;
                animDuration = args.AnimationDuration;
                animCurve = args.AnimationCurve;

                var r = UIKeyboard.FrameBeginFromNotification(args.Notification);
                scrollAmout = r.Height;
                ScrollTheView(true);
            }
        }

        void KeyboardWillHide(object sender, UIKeyboardEventArgs args)
        {
            if (keyboardShowing)
            {
                keyboardShowing = false;
                animDuration = args.AnimationDuration;
                animCurve = args.AnimationCurve;

                var r = UIKeyboard.FrameBeginFromNotification(args.Notification);
                scrollAmout = r.Height;
                ScrollTheView(false);
            }
        }

        private void ScrollTheView(bool scale)
        {
            UIView.BeginAnimations(string.Empty, IntPtr.Zero);
            UIView.SetAnimationDuration(animDuration);
            UIView.SetAnimationCurve(animCurve);

            var frame = View.Frame;

            if (scale)
                frame.Y -= scrollAmout;
            else
                frame.Y += scrollAmout;
            View.Frame = frame;
            UIView.CommitAnimations();
        }
    }
}

Since this renderer actually scrolls the entire native page up and back down when the keyboard shows and hides, it should not matter how you layout the page in the Forms Xaml. All that matters is that your Forms page inherits from WebViewContentPage.

I hope this helps!

[1] https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/contentpage/


Post a Comment for "Xamarin Webview With Form Scrolls Out Of View When Clicking Textbox"