You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms中WebView内置AlertDialog返回后未关闭的解决咨询

解决方案

问题核心在于Web端生成的Alert弹窗由原生WebView控件托管,页面跳转返回后原生控件未主动关闭弹窗。以下分平台给出针对性解决办法:

Android 平台

通过自定义WebChromeClient追踪弹窗状态,结合页面生命周期事件,在页面返回时注入JS关闭弹窗:

public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
    private bool _hasActiveAlert;

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

        if (Control == null)
        {
            var webView = new Android.Webkit.WebView(Context);
            webView.SetWebChromeClient(new CustomWebChromeClient(this));
            SetNativeControl(webView);
        }

        // 绑定/解绑页面生命周期事件
        if (e.NewElement != null)
        {
            var page = Element.Parent as Page;
            page.Appearing += OnPageAppearing;
            page.Disappearing += OnPageDisappearing;
        }
        if (e.OldElement != null)
        {
            var page = e.OldElement.Parent as Page;
            page.Appearing -= OnPageAppearing;
            page.Disappearing -= OnPageDisappearing;
        }
    }

    private void OnPageAppearing(object sender, EventArgs e)
    {
        // 页面返回时,若存在活跃弹窗则执行JS关闭
        if (_hasActiveAlert)
        {
            Control.EvaluateJavascript("window.alert = function(){}; window.close();", null);
            _hasActiveAlert = false;
        }
    }

    private void OnPageDisappearing(object sender, EventArgs e)
    {
        // 页面离开时临时禁用alert方法
        Control.EvaluateJavascript("window.alert = function(){};", null);
    }

    // 自定义WebChromeClient追踪弹窗状态
    private class CustomWebChromeClient : Android.Webkit.WebChromeClient
    {
        private readonly HybridWebViewRenderer _renderer;

        public CustomWebChromeClient(HybridWebViewRenderer renderer)
        {
            _renderer = renderer;
        }

        public override bool OnJsAlert(Android.Webkit.WebView view, string url, string message, Android.Webkit.JsResult result)
        {
            _renderer._hasActiveAlert = true;
            return base.OnJsAlert(view, url, message, result);
        }

        public override void OnJsAlertCanceled(Android.Webkit.WebView view)
        {
            _renderer._hasActiveAlert = false;
            base.OnJsAlertCanceled(view);
        }
    }
}

iOS 平台

通过自定义WKUIDelegate管理弹窗,结合页面生命周期注入JS关闭弹窗:

public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>
{
    private bool _hasActiveAlert;

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

        if (Control == null)
        {
            var config = new WKWebViewConfiguration();
            var webView = new WKWebView(Frame, config);
            webView.UIDelegate = new CustomWKUIDelegate(this);
            SetNativeControl(webView);
        }

        // 绑定/解绑页面生命周期事件
        if (e.NewElement != null)
        {
            var page = Element.Parent as Page;
            page.Appearing += OnPageAppearing;
            page.Disappearing += OnPageDisappearing;
        }
        if (e.OldElement != null)
        {
            var page = e.OldElement.Parent as Page;
            page.Appearing -= OnPageAppearing;
            page.Disappearing -= OnPageDisappearing;
        }
    }

    private void OnPageAppearing(object sender, EventArgs e)
    {
        if (_hasActiveAlert)
        {
            Control.EvaluateJavaScript("window.alert = function(){}; window.close();", (result, error) =>
            {
                if (error == null) _hasActiveAlert = false;
            });
        }
    }

    private void OnPageDisappearing(object sender, EventArgs e)
    {
        Control.EvaluateJavaScript("window.alert = function(){};", null);
    }

    // 自定义WKUIDelegate管理弹窗状态
    private class CustomWKUIDelegate : WKUIDelegate
    {
        private readonly HybridWebViewRenderer _renderer;

        public CustomWKUIDelegate(HybridWebViewRenderer renderer)
        {
            _renderer = renderer;
        }

        public override void RunJavaScriptAlertPanel(WKWebView webView, string message, WKFrameInfo frame, Action completionHandler)
        {
            _renderer._hasActiveAlert = true;
            // 自定义原生弹窗处理
            var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
            alert.AddAction(UIAlertAction.Create("Close", UIAlertActionStyle.Default, _ =>
            {
                completionHandler();
                _renderer._hasActiveAlert = false;
            }));

            var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
            while (rootVC.PresentedViewController != null)
            {
                rootVC = rootVC.PresentedViewController;
            }
            rootVC.PresentViewController(alert, true, null);
        }
    }
}

通用JS交互方案

如果Web端允许配合,可在Forms页面返回时直接注入JS代码强制关闭弹窗:

  1. 在Forms层的HybridWebView定义JS执行接口:
public class HybridWebView : View
{
    public Action<string> EvaluateJavaScript;

    public void ExecuteJs(string script)
    {
        EvaluateJavaScript?.Invoke(script);
    }
}
  1. 在各平台Renderer中实现接口:
    Android:
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
    base.OnElementChanged(e);
    if (e.NewElement != null)
    {
        Element.EvaluateJavaScript = script => Control.EvaluateJavascript(script, null);
    }
}

iOS:

protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
    base.OnElementChanged(e);
    if (e.NewElement != null)
    {
        Element.EvaluateJavaScript = script => Control.EvaluateJavaScript(script, null);
    }
}
  1. 在Forms页面的OnAppearing方法中调用:
protected override void OnAppearing()
{
    base.OnAppearing();
    // 关闭所有弹窗并临时禁用alert
    hybridWebView.ExecuteJs("window.alert = function(){};");
}

内容的提问来源于stack exchange,提问作者I'm Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:20:43