irdalan
irdalan

Reputation: 25

Xamarin Form WebView different behavior between Android and iOS when navigating to link from local html content

When opening a link to a website from my WebView both with Android and iOS I'm able to do it with the default browser of the phone. However, when going back to the app, with Android I see the expected and desired behavior of seeing the original WebView page, instead on iOS I see the opened website inside the application. Here the GitHub link to reproduce the behavior: https://github.com/irdalan/WebViewTestApp

Behavior for Android: From left to right:

  1. AndroidApp before clicking on the link 2. Navigating to link with default browser on Android 3. AndroidApp after going back from browser to App.

AndroidApp before clicking on the link Navigating to link with default browser on Android AndroidApp after going back from browser to App

Behavior for iOS: From left to right:

  1. IphoneApp before clicking on the link 5. Navigating to link with default browser on iOS 6. IphoneApp after going back from browser to App.

IphoneApp before clicking on the link Navigating to link with default browser on iOS IphoneApp after going back from browser to App

EDIT: Code behind of webview page

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace WebViewTestApp
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            HtmlWebViewSource localhtml = new HtmlWebViewSource();


            string text = "<html><body><h1>Xamarin.Forms</h1><p>Welcome to WebView.<a href= \"https://en.wikipedia.org/wiki/Xamarin\">Xamarin</a></p></body></html>";

           
            localhtml.Html = text.Replace(@"\", string.Empty);
            _webview.Source = localhtml;
            _webview.Navigating += async (s, e) =>
            {
                if (e.Url.StartsWith("http"))
                {
                    try
                    {
                        var uri = new Uri(e.Url);
                        await Launcher.OpenAsync(uri);
                    }
                    catch (Exception ex)
                    {

                    }
                    finally
                    {
                        e.Cancel = true;
                    }

                }
            };
        }
    }
}

Upvotes: 1

Views: 897

Answers (1)

ToolmakerSteve
ToolmakerSteve

Reputation: 21213

Try delaying the Launcher call, so that Cancel of Navigating happens before switch to browser happens. This should suppress the default behavior, which is what displayed the web page w/i webview itself.

Change:

await Launcher.OpenASync(uri);

To:

Device.BeginInvokeOnMainThread(async () =>
    await Launcher.OpenAsync(uri));

OPTIONAL:

To make it clear that you want Cancel to happen first, you could move e.Cancel = true; before the Launcher line. However, this isn't strictly necessary: what's inside BeginInvoke won't get executed until your Navigating method returns.

Upvotes: 1

Related Questions