I am trying to create a Custom WebView Renderer for iOS and Android. My main goal is to make the WebView fit it's HTML contents;
After googling, I soon realized that this is only possible by making custom renderers for both iOS and Android.
I am using a solution that requires a delegate. You can view the solution here. However, this solution was posted in 2016 and therefore I get this compile time error message: "'Delegate' was deprecated in iOS 12.0. No longer supported; please adopt 'WKWebView'.
PostWebView.xaml
<WebView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Yoors.Views.Templates.PostWebView" x:Name="WebViewer" BackgroundColor="White" Margin="0, 10, 0, 0" VerticalOptions="FillAndExpand" HeightRequest="1000">
<WebView.Source>
<HtmlWebViewSource Html="{Binding Data.Content}" />
</WebView.Source>
</WebView>
CustomWebViewRenderer.cs
public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
Delegate = new CustomUIWebViewDelegate(this);
}
}
CustomUIWebViewDelegate.cs
public class CustomUIWebViewDelegate : UIWebViewDelegate
{
CustomWebViewRenderer _webViewRenderer;
public CustomUIWebViewDelegate(CustomWebViewRenderer webViewRenderer = null)
{
_webViewRenderer = _webViewRenderer ?? new CustomWebViewRenderer();
}
public override async void LoadingFinished(UIWebView webView)
{
var wv = _webViewRenderer.Element as PostWebView;
if (wv != null)
{
await System.Threading.Tasks.Task.Delay(100); // wait here till content is rendered
wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
}
}
}
How do I adopt WKWebView according to my code?
It's quite easy actually. Create a Custom Webview, something like this:
public class MyWebView : WebView
{
public static readonly BindableProperty UrlProperty = BindableProperty.Create(
propertyName: "Url",
returnType: typeof(string),
declaringType: typeof(MyWebView),
defaultValue: default(string));
public string Url
{
get { return (string)GetValue(UrlProperty); }
set { SetValue(UrlProperty, value); }
}
}
Then in your iOS CustomRenderer do something like this:
[assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
namespace WKWebView.iOS
{
public class MyWebViewRenderer : ViewRenderer<MyWebView, WKWebView>
{
WKWebView _wkWebView;
protected override void OnElementChanged(ElementChangedEventArgs<MyWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var config = new WKWebViewConfiguration();
_wkWebView = new WKWebView(Frame, config);
SetNativeControl(_wkWebView);
}
if (e.NewElement != null)
{
Control.LoadRequest(new NSUrlRequest(new NSUrl(Element.Url)));
}
}
}
}