0

I have an image and custom webview inside a stack and surrounded by a frame like below:

<Frame 
    Padding="5"
    CornerRadius="20"
    Margin="0,10,0,0" 
    Grid.Row="1" 
    x:Name="android_webview_frame" 
    BackgroundColor="#0091DA"
    IsVisible="False">

    <StackLayout
        BackgroundColor="#0091DA">

        <Image
            x:Name="android_saint_image"
            Aspect="AspectFit"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand"
            IsVisible="False"
            Margin="5"/>

        <local:DailySaintAndroidWebView 
            x:Name="android_webview"
            BackgroundColor="#0091DA"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand"/>
    </StackLayout>
</Frame>

In webview I am showing html data and I need to implement scrolling for the entire layout. Currently if i scroll only the webview contents are scrollable. The image is not scroll to top. I have added a scrollview like below but that is not working.

<Frame 
    Padding="5"
    CornerRadius="20"
    Margin="0,10,0,0" 
    Grid.Row="1" 
    x:Name="android_webview_frame" 
    BackgroundColor="#0091DA"
    IsVisible="False">
    
    <ScrollView 
        HorizontalOptions="FillAndExpand"
        VerticalOptions="FillAndExpand">
        
        <StackLayout
            BackgroundColor="#0091DA">

            <Image
                x:Name="android_saint_image"
                Aspect="AspectFit"
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand"
                IsVisible="False"
                Margin="5"/>

            <local:DailySaintAndroidWebView 
                x:Name="android_webview"
                BackgroundColor="#0091DA"
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand"/>
        </StackLayout>
    </ScrollView>
</Frame>

The issue here is that WebView has its own internal scrolling mechanism, which conflicts with the ScrollView. So I tried to disable scrolling inside the WebView so that the entire ScrollView can handle the scrolling.

Android customwebview:

[assembly: ExportRenderer(typeof(DailySaintAndroidWebView), typeof(DailySaintAndroidRenderer))]
namespace OfficeName.Droid.Renderer
{
    public class DailySaintAndroidRenderer : WebViewRenderer
    {
        public DailySaintAndroidRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Microsoft.Maui.Controls.WebView> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                // Set default font size
                Control.Settings.DefaultFontSize = 25;
                Control.Settings.JavaScriptEnabled = true; // Ensure JavaScript is enabled

                // Disable WebView scrolling
                Control.SetOnTouchListener(new CustomTouchListener());

                // Inject CSS to change text color to white
                string changeTextColorScript = @"
                let style = document.createElement('style');
                style.innerHTML = 'body, p, h1, h2, h3, h4, h5, h6 { color: white !important; background-color: #0091DA !important; }';
                document.head.appendChild(style);
            ";

                Control.SetWebViewClient(new CustomWebViewClient(changeTextColorScript));
            }
        }

        private class CustomWebViewClient : WebViewClient
        {
            private readonly string _script;

            public CustomWebViewClient(string script)
            {
                _script = script;
            }

            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                base.OnPageFinished(view, url);

                // Execute JavaScript to inject the CSS
                view.EvaluateJavascript(_script, null);
            }
        }
    }

    public class CustomTouchListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
    {
        public bool OnTouch(View v, MotionEvent e)
        {
            if (e.Action == MotionEventActions.Move)
            {
                v.Parent?.RequestDisallowInterceptTouchEvent(false);
            }
            return false;
        }   
    }
}

ios customwebview

[assembly: ExportRenderer(typeof(DailySaintWebView), typeof(DailySaintWebViewRenderer))]
namespace OfficeName.Platforms.iOS.Renderer
{
    public class DailySaintWebViewRenderer : ViewRenderer<DailySaintWebView, WKWebView>
    {
        WKWebView _wkWebView;

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

            if (Control == null)
            {
                var config = new WKWebViewConfiguration();
                config.AllowsInlineMediaPlayback = true;
                _wkWebView = new WKWebView(Frame, config);
                //transparent background
                _wkWebView = new WKWebView(CGRect.Empty, config);
                _wkWebView.BackgroundColor = UIColor.Clear;
                _wkWebView.ScrollView.BackgroundColor = UIColor.Clear;
                _wkWebView.Opaque = false;
                _wkWebView.NavigationDelegate = new MyNavigationDelegate();
                SetNativeControl(_wkWebView);
                
            }
        }

        public class MyNavigationDelegate : WKNavigationDelegate
        {
            public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
            {
                string fontSize = Device.Idiom == TargetIdiom.Phone ? "500%" : "750%";

                string adjustTextSizeScript = $"document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '{fontSize}';";
                string changeTextColorScript = @"
                    let style = document.createElement('style');
                    style.innerHTML = 'body, p, h1, h2, h3, h4, h5, h6 { color: white !important; }';
                    document.head.appendChild(style);
                ";

                WKJavascriptEvaluationResult handler = (NSObject result, NSError err) =>
                {
                    if (err != null)
                    {
                        System.Console.WriteLine(err);
                    }
                    if (result != null)
                    {
                        System.Console.WriteLine(result);
                    }
                };

                webView.EvaluateJavaScript(adjustTextSizeScript, handler);
                webView.EvaluateJavaScript(changeTextColorScript, handler);
            }


        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == "Url")
            {
                string finalHtml = Element.Url.Replace("width=\"640\"", "width=\"1000\"");
                Control.LoadHtmlString(finalHtml, null);
            }
        }
    }
}

But it is not working, so how can I disable scrolling of custom webview in android and ios and make the scrollview to scroll the entire data?

1 Answer 1

0

I think defining your layout properly will stretch the WebView and its content, allowing you to scroll the entire page using MAUI Scrollview as intended. You can test this with a default .NET MAUI screen like this:

<ScrollView>
    <VerticalStackLayout
        Padding="30,0"
        Spacing="25">
        
        <Image
            Source="dotnet_bot.png"
            HeightRequest="185"
            Aspect="AspectFit"
            SemanticProperties.Description="dot net bot in a race car number eight" />

        <Label
            Text="Hello, World!"
            Style="{StaticResource Headline}"
            SemanticProperties.HeadingLevel="Level1" />

        <Label
            Text="Welcome to &#10;.NET Multi-platform App UI"
            Style="{StaticResource SubHeadline}"
            SemanticProperties.HeadingLevel="Level2"
            SemanticProperties.Description="Welcome to dot net Multi platform App U I" />

        <Button
            x:Name="CounterBtn"
            Text="Click me"
            SemanticProperties.Hint="Counts the number of times you click"
            Clicked="OnCounterClicked"
            HorizontalOptions="Fill" />

        <WebView 
            Source="https://www.pexels.com/"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="FillAndExpand"/>
            
    </VerticalStackLayout>
</ScrollView>

Disabling Scrolling in WebView:

If you want to disable scrolling inside the WebView so that the ScrollView can handle scrolling for the entire page, try the following approaches:

For Android:

if (Control is global::Android.Webkit.WebView platformWebView) 
{
    platformWebView.SetOnTouchListener(new WebViewTouchListener());
}

// Custom touch listener class
public class WebViewTouchListener : Java.Lang.Object, global::Android.Views.View.IOnTouchListener
{
    public bool OnTouch(Android.Views.View? v, global::Android.Views.MotionEvent? e)
    {
        return e.Action == global::Android.Views.MotionEventActions.Move;
    }
}

For iOS:

_wkWebView.ScrollView.ScrollEnabled = false;
Sign up to request clarification or add additional context in comments.

10 Comments

I tried the scrollview disable on both android and ios custom webview. The webview's scrollview is disabled but the entire layout scrolling is not working.
I also tried the sample layout you have shared initially and it is working fine.
@MatthewPans Use VerticalStackLayout instead of StackLayout and using Frame is also not recommended use Border instead` ....I f these dont work try Grid as parent container inside your scrollview instead of StackLayout
I tried that also but scrolling is not working. Can I create a demo project and share with you?
Could you please check the below demo project. I have added an image and webview in the UI but it is not scrollable. It is the exact copy of my real project, so i removed the other layouts to replicate this issue. drive.google.com/file/d/1L6L5BjHt0WgpnSf4Gos4znSQUBR96j5c/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.