简体   繁体   中英

Adding UIWebView inside UIScrollView XAMARIN.IOS C#

I'd like to add a UIWebView (and some other elements) in a UIScrollView.

First of all, my UIWebView has not a fix text and could be change.

So, as I saw in examples and tutorials I can do it like this:

public class testArticleViewController : UIViewController
    {
        private UIScrollView _scrollView;

        //Post elements
        UIWebView _artcileTextWeb;

        public testArticleViewController()
        {
            Title = "test";
            View.BackgroundColor = UIColor.White;


        }

        public override void ViewDidLoad()
        {

            string text = @"L'un des deux meilleurs du monde, Lionel Messi, va-t-il manquer la Coupe du monde&nbsp;? L'Argentine se retrouve dans une situation extr&ecirc;mement d&eacute;licate dans la course &agrave; la qualification au Mondial 2018 en faisant match nul (0-0) jeudi face au P&eacute;rou.<br />
<div>
<div>
<div>
<article>
<div>
<div>
<p ><br />Le risque de voir une Coupe du Monde en Russie sans Lionel Messi est bien r&eacute;el&nbsp;: sixi&egrave;me et en dehors de la zone de qualification &agrave; une journ&eacute;e de la fin, l'Albiceleste doit imp&eacute;rativement s'imposer mardi face &agrave; l'&Eacute;quateur, d&eacute;j&agrave; &eacute;limin&eacute;.<br /><br />Cinq &eacute;quipes se tiennent en deux points, entre le Chili (3e, 26 points) et le Paraguay (7e, 24 points) qui garde un mince espoir de qualification gr&acirc;ce &agrave; son succ&egrave;s de jeudi (2-1) face &agrave; la Colombie (4e, 26 points).<br /><br />L'Argentine ne pointe qu'en sixi&egrave;me position, avec le m&ecirc;me nombre de points que les P&eacute;ruviens (5e, 25), qui occupent pour le moment une place de barragiste et r&ecirc;vent &agrave; une premi&egrave;re participation au Mondial depuis 1982.</p>
<h3>Sampaoli est &laquo;tr&egrave;s confiant&raquo;</h3>
<p>M&ecirc;me s'il admet que la position de l'Argentine <em>&laquo;n'est pas tr&egrave;s confortable&raquo;</em>, le s&eacute;lectionneur Jorge Sampaoli se veut <em>&laquo;tr&egrave;s confiant dans le fait que nous allons &ecirc;tre au Mondial&raquo;</em>. Pour le match crucial de jeudi face au P&eacute;rou, la F&eacute;d&eacute;ration argentine avait mis&eacute; sur l'ambiance bouillante du mythique stade de la Bombonera.<br /><br />Pouss&eacute;s par quelque 50 000 supporters, les locaux ont eu beaucoup de mal &agrave; trouver des espaces face &agrave; des P&eacute;ruviens bien regroup&eacute;s derri&egrave;re. Messi a cru ouvrir le score d&egrave;s la 13e minute, sur une belle combinaison sur corner, mais un d&eacute;fenseur s'est jet&eacute; in extremis pour d&eacute;vier un ballon qui semblait prendre la direction des filets. La Bombonera a soupir&eacute; une nouvelle fois dix minutes plus tard, quand Di Maria - remplac&eacute; &agrave; la pause - a manqu&eacute; une belle occasion en tirant au-dessus.<br /><br />Les nerfs &agrave; vif, les supporters ont retenu leur souffle &agrave; la 33e, en voyant Farfan manquer le cadre de peu sur un centre &agrave; ras de terre Trauco. Messi bien touch&eacute; le poteau au retour des vestiaires, mais l'Albiceleste a livr&eacute; une nouvelle fois une copie bien p&acirc;le. <em>&laquo;On ne peut pas en demander plus &agrave; Leo Messi. Il a eu des opportunit&eacute;s, les a cr&eacute;&eacute;es, a eu des balles de but. On a eu un Messi tr&egrave;s intense, celui dont l'Argentine a besoin&raquo;</em>, a consid&eacute;r&eacute; Sampaoli.<br /><br />La derni&egrave;re fois que l'Albiceleste a rat&eacute; un Mondial (celui de 1970, au Mexique), elle avait &eacute;t&eacute; condamn&eacute;e par un match nul (2-2) face au P&eacute;rou, dans ce m&ecirc;me stade de la Bombonera. Cette fois, il reste encore un match, un seul, pour tout changer.</p>
</div>
</div>
</article>
</div>
</div>
</div>";



            var padding = 10;

            View.BackgroundColor = UIColor.White;

            _scrollView = new UIScrollView()
            { ShowsHorizontalScrollIndicator = false, AutoresizingMask = UIViewAutoresizing.FlexibleHeight };

            //Text article
            _artcileTextWeb = new UIWebView();
            _artcileTextWeb.LoadHtmlString(text, null);
            _artcileTextWeb.ScrollView.ScrollEnabled = false;


            var view1 = new UIView { BackgroundColor = UIColor.Blue };
            var view3 = new UIView { BackgroundColor = UIColor.Green };


            Add(_scrollView);

            View.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

            View.AddConstraints(
                _scrollView.AtLeftOf(View),
                _scrollView.AtTopOf(View),
                _scrollView.WithSameWidth(View),
                _scrollView.WithSameHeight(View));

            _scrollView.Add(view1);
            _scrollView.Add(_artcileTextWeb);
            _scrollView.Add(view3);




            _scrollView.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();

            var basicwidth = (UIScreen.MainScreen.Bounds.Width - 3 * padding) / 2;
            var basicheight = basicwidth / 2;

            _scrollView.AddConstraints(
                view1.AtTopOf(_scrollView, UIApplication.SharedApplication.StatusBarFrame.Height),
                view1.AtLeftOf(_scrollView, padding),
                view1.Width().EqualTo(basicwidth),
                view1.Height().EqualTo(basicheight),

                view3.WithSameTop(view1),
                view3.Left().EqualTo().RightOf(view1).Plus(padding),
                view3.WithSameHeight(view1),
                view3.WithSameWidth(view1),

                _artcileTextWeb.Below(view1, padding),
                _artcileTextWeb.WithSameLeft(view1),
                _artcileTextWeb.WithSameRight(view3),
                _artcileTextWeb.WithSameHeight(_scrollView)

            );
        }



    }

If you run it, you will see that the UIScrollView has the same height of screen and it's not dynamic!

So, maybe it seems that the UIWebView has not a correct height (has not a corrected frame size)! If it's the case, how can I predict the Height of UIWebView?

Even if I use CGRect for creating adding UIWebView's frame to my UIScrollView, I need a Height for it!

Do you have any idea dear developers?

Re: Autolayouts in UIScrollView using Cirrious.FluentLayouts.Touch

The correct solution:

Set the contentSize of UIWebView , and then let it AtBottomOf Scrollview .

Round 1

_artcileTextWeb.Below(view1, padding),
_artcileTextWeb.WithSameLeft(view1),
_artcileTextWeb.WithSameRight(view3),
_artcileTextWeb.Height().EqualTo(_artcileTextWeb.ScrollView.ContentSize.Height),
_artcileTextWeb.AtBottomOf(_scrollView)

But it didn't work , ScrollView.ContentSize.Height returns the incorrect result.

Round 2

_artcileTextWeb = new UIWebView(UIScreen.MainScreen.Bounds);
_artcileTextWeb.LoadHtmlString(text, null);
_artcileTextWeb.ScrollView.ScrollEnabled = false;
string result = _artcileTextWeb.EvaluateJavascript("document.body.offsetHeight;");
int height = Convert.ToInt32(result); 


_scrollView.AddConstraints(
            //xxxx

            _artcileTextWeb.Below(view1, padding),
            _artcileTextWeb.WithSameLeft(view1),
            _artcileTextWeb.WithSameRight(view3),
            _artcileTextWeb.Height().EqualTo(height),
            _artcileTextWeb.AtBottomOf(_scrollView)

        );

The result always returns 667 (the screen height), so I move calculation to the method LoadingFinished ,set the content height after webview has finished loading.

Round 3

New a subclass of UIWebViewDelegate

class MyDelegate : UIWebViewDelegate
{
    UIScrollView mainView;
    public MyDelegate(UIScrollView view) {
        mainView = view;
    }

    public override void LoadingFinished(UIWebView webView)
    {
        string result = webView.EvaluateJavascript("document.body.offsetHeight;");
        mainView.AddConstraints(webView.Height().EqualTo(Convert.ToInt64(result)));
    }
}

In ViewController

_artcileTextWeb = new UIWebView(UIScreen.MainScreen.Bounds);
_artcileTextWeb.Delegate = new MyDelegate(_scrollView);
_artcileTextWeb.LoadHtmlString(text, null);
_artcileTextWeb.ScrollView.ScrollEnabled = false;

 _artcileTextWeb.Below(view1, padding),
 _artcileTextWeb.AtLeftOf(_scrollView),    //modify this line
 _artcileTextWeb.WithSameWidth(_scrollView), //modify this line
 _artcileTextWeb.AtBottomOf(_scrollView)

At last, it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM