Cause:
Click action will conflict with native JS action.
Solution:
You can use CustomRenderer to add a TapGestureRecognizer
and let webview recognize it.Then use MessagingCenter
to pass notification when you click the webview.Refer to the following code.
in Forms
using System;
using Xamarin.Forms;
namespace xxx
{
public class MyWebView:WebView
{
public MyWebView()
{
}
}
}
in iOS project
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using UIKit;
using Foundation;
using ObjCRuntime;
[assembly:ExportRenderer(typeof(MyWebView),typeof(MyWebViewRenderer))]
namespace xxx.iOS
{
public class MyWebViewRenderer:WebViewRenderer, IUIGestureRecognizerDelegate
{
public MyWebViewRenderer()
{
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if(NativeView!=null)
{
UITapGestureRecognizer tapGestureRecognizer = new UITapGestureRecognizer(this, new Selector("HandleTap:"))
{
WeakDelegate = this,
CancelsTouchesInView = false
};
NativeView.AddGestureRecognizer(tapGestureRecognizer);
}
}
[Export("gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:")]
public bool ShouldRecognizeSimultaneously(UIGestureRecognizer gestureRecognizer, UIGestureRecognizer otherGestureRecognizer)
{
return true;
}
[Export("HandleTap:")]
void HandleTap(UITapGestureRecognizer tap)
{
MessagingCenter.Send<Object>(this,"webviewClicked");
}
}
}
in Android Project
using System;
using Android.Content;
using Android.Webkit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
namespace xxx.Droid
{
public class MyWebViewRenderer:WebViewRenderer
{
public MyWebViewRenderer(Context context):base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if(Control!=null)
{
Control.SetWebViewClient(new MyWebviewClient());
Control.Touch+= (object sender, TouchEventArgs eventArgs) => {
if(eventArgs.Event.Action==Android.Views.MotionEventActions.Down)
{
MessagingCenter.Send<Object>(this, "webviewClicked");
}
};
}
}
}
internal class MyWebviewClient: WebViewClient
{
public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
{
return true;
}
}
}
Now you can hide the ActivityIndicator
when you click the webview
in xxxpage.xaml
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ActivityIndicator x:Name="PageLoader" IsRunning="true" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"></ActivityIndicator>
<local:MyWebView Source="xxx" IsVisible="true" x:Name="MainContent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
</local:MyWebView>
</StackLayout>
in code behind
public partial class xxxPage : ContentPage
{
public xxxPage()
{
InitializeComponent();
MessagingCenter.Subscribe<Object>(this, "webviewClicked", (obj) =>
{
// you can hide the ActivityIndicator here.
});
}
}