1

I have a sample application in Xamarin.form, which use to showing local HTML content in webview.

I want to use the navigation event to change the content of webview.

It working fine in Android but in IOS not getting navigation URL. In IOS navigation getting the full path of IOS application like...

 file://locationpathofIOSapplication/WorkingWithWebviewiOS.app
public class LocalHtml : ContentPage
{
    public LocalHtml()
    {
        var browser = new WebView();
        var htmlSource = new HtmlWebViewSource();
        htmlSource.Html = @"<html><body>
                            <h1 onclick=""window.location='Navigation://yahoo'"">Xamarin.Forms</h1>
                            </br> </br></br>
                            <a href=""Navigation://google""> Click on me</a>
                            </br> </br></br>
                            <p>Welcome to WebView Test Navigation.</p>
                            </body>
                            </html>";
        browser.Source = htmlSource;
        Content = browser;
        browser.Navigated += Browser_Navigated;
    }

    private void Browser_Navigated(object sender, WebNavigatedEventArgs e)
    {
        string url = e.Url;
        if(url == "google")
        {
            //do some action
        }
        else if(url == "yahoo")
        {
            //do some action
        }
    }
}

1 Answer 1

1

You can use custom renderer to get the navigation URL in IOS:

In xamarin.forms, use MessagingCenter to Subscribe the url:

public partial class MainPage : ContentPage
{

    public MainPage()
    {

        InitializeComponent();

        var browser = new myWebView();
        var htmlSource = new HtmlWebViewSource();
        htmlSource.Html = @"<html><body>
                        <h1 onclick=""window.location='Navigation://yahoo'"">Xamarin.Forms</h1>
                        </br> </br></br>
                        <a href=""Navigation://google""> Click on me</a>
                        </br> </br></br>
                        <p>Welcome to WebView Test Navigation.</p>
                        </body>
                        </html>";
        browser.Source = htmlSource;
        Content = browser;
        browser.Navigated += Browser_Navigated;


        MessagingCenter.Subscribe<Object,string>(this, "shouldLoadUrl", (sender, arg) => {
            // do something whenever the "shouldLoadUrl" message is sent

            //arg is the url 
            Console.WriteLine(arg);

            myAction(arg);
        });

    }

    private void Browser_Navigated(object sender, WebNavigatedEventArgs e)
    {
        string url = e.Url;

        if (url.StartsWith("file:"))
        {
            return;
        }

        myAction(url);
    }

    public void myAction(string url) {

        if (url == "google")
        {
            //do some action
        }
        else if (url == "yahoo")
        {
            //do some action
        }
    }
}

public class myWebView : WebView {

}

In the iOS project, get the url string in ShouldStartLoad method and handle your logic there:

[assembly: ExportRenderer(typeof(myWebView), typeof(myWebRender))]

namespace App452.iOS
{
    class myWebRender :  WebViewRenderer
    {

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement == null)
            {   // perform initial setup
                UIWebView myWebView = (UIWebView)this.NativeView;

                myWebView.Delegate = new CustomWebViewDelegate();             
            }
        }

        public class CustomWebViewDelegate : UIWebViewDelegate
        {
            public CustomWebViewDelegate()
            {
            }

            public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
            {

                Console.WriteLine(request.Url.AbsoluteString);
                //Handle your logic here

                MessagingCenter.Send<Object>(new Object(), "shouldLoadUrl",request.Url.AbsoluteString);
                return true.
            }

        }
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Error after use delegate {Foundation.You_Should_Not_Call_base_In_This_Method: Exception of type 'Foundation.You_Should_Not_Call_base_In_This_Method' was thrown.
@user619 Remove the line return base.ShouldStartLoad(webView, request, navigationType); and return true/false depending on your own situation.
but also getting full URL in field request.Url.AbsoluteString.
@user619 I just test, when you click the "Click on me", you will get the url. When you first load the page, you will get the full path. Right? That's what you want when you click the "Click on me"?
@user619 Use a messageCenter would work, see my edited answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.