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代码强制关闭弹窗:
- 在Forms层的
HybridWebView定义JS执行接口:
public class HybridWebView : View { public Action<string> EvaluateJavaScript; public void ExecuteJs(string script) { EvaluateJavaScript?.Invoke(script); } }
- 在各平台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); } }
- 在Forms页面的
OnAppearing方法中调用:
protected override void OnAppearing() { base.OnAppearing(); // 关闭所有弹窗并临时禁用alert hybridWebView.ExecuteJs("window.alert = function(){};"); }
内容的提问来源于stack exchange,提问作者I'm Coder
相关产品推荐
相关产品推荐

