Как сделать так, чтобы высота WKWebView соответствовала его содержимому в Xamarin с помощью CustomWebViewRenderer? - PullRequest
0 голосов
/ 25 мая 2019

Я сделал пользовательский рендерер веб-просмотра для iOS, где я вручную заменяю пользовательский веб-вид на WKWebView. Однако моя главная цель - настроить WKWebView по высоте в соответствии с его содержимым. Его содержимое состоит из предопределенной HTML-строки с телом.

Прямо сейчас это отключает веб-просмотр, а остальная часть контента забивается в виде прокрутки. Изображения и текст, которые я помещаю перед просмотром в Интернете, также остаются неизменными, хотя я хочу, чтобы они тоже прокручивались вниз. Мне не нужна полоса прокрутки для веб-просмотра, я просто хочу, чтобы веб-просмотр имел истинный размер содержимого, чтобы пользователь мог провести пальцем вверх, чтобы просмотреть весь текст.

CustomWebViewRenderer.cs

[assembly: ExportRenderer(typeof(PostWebView), typeof(Yoors.iOS.CustomWebViewRenderer))]
namespace Yoors.iOS
{
    public class CustomWebViewRenderer : ViewRenderer<PostWebView, WKWebView>
    {
        WKWebView _wkWebView;
        protected override void OnElementChanged(ElementChangedEventArgs<PostWebView> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                WKWebViewConfiguration config = new WKWebViewConfiguration();

                _wkWebView = new WKWebView(Frame, config);


                SetNativeControl(_wkWebView);
            }
            if (e.NewElement != null)
            {

                HtmlWebViewSource source = (Xamarin.Forms.HtmlWebViewSource)Element.Source;
                string headerString = "<header><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0'></header>";
                string html= headerString + source.Html;
                Console.WriteLine("Height" + Element);
                _wkWebView.LoadHtmlString(html, baseUrl: null);
                _wkWebView.ScrollView.ScrollEnabled = false;
                _wkWebView.SizeToFit();
            }




        }
    }

PostWebView.xaml

<?xml version="1.0" encoding="UTF-8"?>
<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>

PostView.xaml

 <ContentPage.Content>
        <ScrollView>
            <StackLayout BackgroundColor="White" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                <!-- Header of the post-->
                <Image HeightRequest="125" Aspect="AspectFill" Source="{Binding Post.ImageUrl}" />
                <StackLayout BackgroundColor="White" Padding="1" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Margin="10, 0,10, 0">
                    <Label Text="{Binding Post.Title}" FontFamily="{StaticResource BoldFont}" FontSize="20" />
                    <Label Text="{Binding Post.CreatedOn.DisplayText}" FontSize="12" />
                    <!-- Content of the post in a HTML view-->
                </StackLayout>
                <templates:PostWebView VerticalOptions="FillAndExpand" BindingContext="{Binding Post}">
                </templates:PostWebView>
                <templates:CommentView BindingContext="{Binding CommentsViewModel}">
                    <x:Arguments>
                        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
                    </x:Arguments>
                </templates:CommentView>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>

Я думал, что размещение VerticalOptions = "FillAndExpand" для PostWebView позволит подогнать его под размер его содержимого, не создавая полосу прокрутки и, следовательно, не фиксируя другое содержимое на месте, но просто делает это: [![this][1]][1]. Кто-нибудь знает, как помочь?

1 Ответ

0 голосов
/ 25 мая 2019

Я ответил на свой собственный вопрос, сделав CustomNavigationDelegate, который регистрируется после завершения загрузки Webview.

CustomNavigationDelegate.cs

public class CustomWKNavigationDelegate : WKNavigationDelegate
    {

        CustomWebViewRenderer _webViewRenderer;

        public CustomWKNavigationDelegate(CustomWebViewRenderer webViewRenderer)
        {
            _webViewRenderer = webViewRenderer;
        }

        public  override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
       {
            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;
            }
        }
    }

Затем в OnElementChanged CustomWebViewRenderer, который я показал выше, я назначаю делегат навигации для WKWebView.

CustomWebViewRenderer.cs

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


            if (Control == null)
            {
                WKWebViewConfiguration config = new WKWebViewConfiguration();

                _wkWebView = new WKWebView(Frame, config);
                _wkWebView.NavigationDelegate = new CustomNavigationDelegate(this);
...

Это позволит WKWebView иметь размер своего содержимого !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...