TJP
TJP

Reputation: 43

Xamarin.Forms - Strange height issue with my responsive WebViews on iOS

I have a ListView and inside that I want to bind multiple webviews which all vary in height. I want to calculate the height of each webview based on it's content and display it accordingly.

It works on Android - on iOS all WebViews are FAR too big

       await System.Threading.Tasks.Task.Delay(100);
       var result = (double)webView.ScrollView.ContentSize.Height;
       _webView.HeightRequest = result;

The strange thing is: the MORE html characters the webview has, the bigger it gets. So I could add just one character and another 50px will be added to the height.

It is a lot of code to post here but here is a link to the project on github: https://github.com/SlimboTimbo/MultipleWebViews

Upvotes: 0

Views: 803

Answers (1)

Junior Jiang
Junior Jiang

Reputation: 12723

After checking the project , have found the reason why not works in iOS Device .

The reason is that the width of webView.ScrollView.ContentSize is not correct , is too small that is 27 . Therefore , it can not show correctly .

System.Console.WriteLine("----" + resultWidth + "-----"+ resultHeight + "----"+ _webView.Width);

Output :

2020-06-04 11:19:58.066542+0800 MultipleWebViews.iOS[50674:1690400] ----27-----642----375

Solution :

You can caluculate the height by the width of HybridWebView, and set the calcualted height for HybridWebView .

DidFinishNavigation method code as follow :

public override async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{

    try
    {
        var _webView = webViewRenderer.Element as HybridWebView;
        if (_webView != null)
        {
            await System.Threading.Tasks.Task.Delay(100);
            var resultWidth = (double)webView.ScrollView.ContentSize.Width;
            var resultHeight = (double)webView.ScrollView.ContentSize.Height;
            System.Console.WriteLine("----" + resultWidth + "-----"+ resultHeight + "----"+ _webView.Width);

            double result = MeasureTextHeightSize(_webView.messageContent, _webView.Width, UIFont.LabelFontSize, null);

            _webView.HeightRequest = result;

            MessagingCenter.Send<Object, PassModel>(this, "LoadFinished", new PassModel(_webView.Id, Convert.ToDouble(result)));
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error at HybridWebViewRenderer LoadingFinished: " + ex.Message);
    }
}

MeasureTextHeightSize ( Calculate the height method )

private double MeasureTextHeightSize(string text, double width, double fontSize, string fontName = null)
{
    var nsText = new NSString(text);
    var boundSize = new SizeF((float)width, float.MaxValue);
    var options = NSStringDrawingOptions.UsesFontLeading | NSStringDrawingOptions.UsesLineFragmentOrigin;

    if (fontName == null)
    {
        fontName = "HelveticaNeue";
    }

    var attributes = new UIStringAttributes
    {
        Font = UIFont.FromName(fontName, (float)fontSize)
    };

    var sizeF = nsText.GetBoundingRect(boundSize, options, attributes, null).Size;

    //return new Xamarin.Forms.Size((double)sizeF.Width, (double)sizeF.Height);
    return (double)sizeF.Height;
}

The Effect :

enter image description here

Note : You can modify the fontSize of this method according to your current system font size . And also can custom the return value ,such as return (double)sizeF.Height + 10 to fit screen .

Upvotes: 1

Related Questions