0
votes

I followed the example - https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/hybridwebview/ to create a hybrid web view. It works fine in Andriod project but I have issues with the iOS project. In the OnElementChanged override, the Element property is always Xamarin.Forms.Element type which is the base type and not my generic view type (TElement). I have rechecked my code multiple times but cannot find any fixes. If I download the original code and run it, it works fine. The issue is only in my project.

Can anybody give me pointers as to why I might not be getting the generic TElement type. In the original project , the TElement type is HybridWebView. In mine I have a different name but with almost all the same properties and methods.

Below are some of my code. It is really easy to replicate the issue. Just create a new Xamarin.Forms solution and add my code. You will see the issue on this lie - var ele = Element; //ELEMENT HERE IS NOt SBMHybridWebView

The custom control in PCL

    public class SBMHybridWebView : Xamarin.Forms.View
{
}

The iOS Renderer (off-course I have added the ExportRenderer)

    public class SBMHybridWebViewRenderer : ViewRenderer<SBMHybridWebView, WKWebView>, IWKScriptMessageHandler
{
    const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
    WKUserContentController userController;

    protected override void OnElementChanged(ElementChangedEventArgs<SBMHybridWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            userController = new WKUserContentController();
            var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
            userController.AddUserScript(script);
            userController.AddScriptMessageHandler(this, "invokeAction");

            var config = new WKWebViewConfiguration { UserContentController = userController };
            var webView = new WKWebView(Frame, config);
            SetNativeControl(webView);
        }
        if (e.OldElement != null)
        {
            //Clean up code
        }
        if (e.NewElement != null)
        {
            var ele = Element; //ELEMENT HERE IS NOt SBMHybridWebView
        }
    }

    public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
    {
        //Element.InvokeAction(message.Body.ToString());
    }
}

The XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:localcontrol="clr-namespace:App2.Control;assembly=App2"
             x:Class="App2.View.Page1">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="*" />
      <RowDefinition Height="60" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <localcontrol:SBMHybridWebView Grid.Row="0" />
  </Grid>
</ContentPage>
1
Add the relevant parts of your code to the question. It's very hard to help without more information.Tim Klingeleers
I have edited the postAmitesh

1 Answers

0
votes

I found the cause which I cannot explain. In my iOS project, I had my SBMHybridWebViewRenderer in Renderer folder. Somehowm iOS does not like the renderer to be in a folder. Moving it to the root of the project (but keeping the same namespace) solved the issue. WHY? I dont know. I would have expected it to work regardless of where I place the file.

I thought I will post this just incase someone else has the same issue.