diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846.xaml b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846.xaml
new file mode 100644
index 000000000000..97b83ee4f6fa
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846.xaml.cs b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846.xaml.cs
new file mode 100644
index 000000000000..7e3cc3e505d7
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846.xaml.cs
@@ -0,0 +1,22 @@
+using System;
+using Microsoft.Maui;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Controls.Xaml;
+
+namespace Maui.Controls.Sample.Issues
+{
+ [XamlCompilation(XamlCompilationOptions.Compile)]
+ [Issue(IssueTracker.Github, 21846, "Fix crash closing Popup with WebView", PlatformAffected.iOS)]
+ public partial class Issue21846 : ContentPage
+ {
+ public Issue21846()
+ {
+ InitializeComponent();
+ }
+
+ async void OnButtonClicked(object sender, System.EventArgs e)
+ {
+ await Navigation.PushModalAsync(new Issue21846Modal());
+ }
+ }
+}
diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846Modal.xaml b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846Modal.xaml
new file mode 100644
index 000000000000..7c6a0d4993bb
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846Modal.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846Modal.xaml.cs b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846Modal.xaml.cs
new file mode 100644
index 000000000000..617d30c9037a
--- /dev/null
+++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21846Modal.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using Microsoft.Maui;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Controls.Xaml;
+
+namespace Maui.Controls.Sample.Issues
+{
+ [XamlCompilation(XamlCompilationOptions.Compile)]
+ public partial class Issue21846Modal : ContentPage
+ {
+ public Issue21846Modal()
+ {
+ InitializeComponent();
+
+ BindingContext = this;
+ }
+
+ async void OnButtonClicked(object sender, System.EventArgs e)
+ {
+ if (TestWebView is IElement visualElement)
+ {
+ if (visualElement.Handler != null)
+ {
+ if (visualElement.Handler is IDisposable disposableHandler)
+ disposableHandler.Dispose();
+
+ visualElement.Handler.DisconnectHandler();
+ }
+ }
+
+ await Navigation.PopModalAsync();
+ }
+ }
+}
diff --git a/src/Controls/tests/UITests/Tests/Issues/Issue21846.cs b/src/Controls/tests/UITests/Tests/Issues/Issue21846.cs
new file mode 100644
index 000000000000..5332e44725fe
--- /dev/null
+++ b/src/Controls/tests/UITests/Tests/Issues/Issue21846.cs
@@ -0,0 +1,28 @@
+using NUnit.Framework;
+using UITest.Appium;
+using UITest.Core;
+
+namespace Microsoft.Maui.AppiumTests.Issues
+{
+ public class Issue21846 : _IssuesUITest
+ {
+ public Issue21846(TestDevice device) : base(device)
+ {
+ }
+
+ public override string Issue => "Fix crash closing Popup with WebView";
+
+ [Test]
+ [Category(UITestCategories.WebView)]
+ public void WebViewNoCrashPopup()
+ {
+ this.IgnoreIfPlatforms([TestDevice.Android, TestDevice.Windows]);
+
+ App.WaitForElement("OpenModalButton");
+ App.Click("OpenModalButton");
+
+ App.WaitForElement("CloseModalButton");
+ App.Click("CloseModalButton");
+ }
+ }
+}
diff --git a/src/Core/src/Platform/iOS/MauiWebViewNavigationDelegate.cs b/src/Core/src/Platform/iOS/MauiWebViewNavigationDelegate.cs
index 6f1a916c218b..3000e3ec430d 100644
--- a/src/Core/src/Platform/iOS/MauiWebViewNavigationDelegate.cs
+++ b/src/Core/src/Platform/iOS/MauiWebViewNavigationDelegate.cs
@@ -26,12 +26,17 @@ public MauiWebViewNavigationDelegate(IWebViewHandler handler)
public void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
var handler = Handler;
+
+ if (handler is null || !handler.IsConnected())
+ return;
+
+ var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;
- if (handler == null || virtualView == null)
+ if (platformView is null || virtualView is null)
return;
- handler.PlatformView?.UpdateCanGoBackForward(handler.VirtualView);
+ platformView.UpdateCanGoBackForward(virtualView);
if (webView.IsLoading)
return;
@@ -47,39 +52,49 @@ public void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
if (handler is WebViewHandler webViewHandler)
webViewHandler.ProcessNavigatedAsync(url).FireAndForget();
else
- handler.PlatformView?.UpdateCanGoBackForward(virtualView);
+ platformView.UpdateCanGoBackForward(virtualView);
}
[Export("webView:didFailNavigation:withError:")]
public void DidFailNavigation(WKWebView webView, WKNavigation navigation, NSError error)
{
var handler = Handler;
+
+ if (handler is null || !handler.IsConnected())
+ return;
+
+ var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;
- if (handler == null || virtualView == null)
+ if (platformView is null || virtualView is null)
return;
var url = GetCurrentUrl();
virtualView.Navigated(_lastEvent, url, WebNavigationResult.Failure);
- handler.PlatformView?.UpdateCanGoBackForward(virtualView);
+ platformView.UpdateCanGoBackForward(virtualView);
}
[Export("webView:didFailProvisionalNavigation:withError:")]
public void DidFailProvisionalNavigation(WKWebView webView, WKNavigation navigation, NSError error)
{
var handler = Handler;
+
+ if (handler is null || !handler.IsConnected())
+ return;
+
+ var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;
- if (handler == null || virtualView == null)
+ if (platformView is null || virtualView is null)
return;
var url = GetCurrentUrl();
virtualView.Navigated(_lastEvent, url, WebNavigationResult.Failure);
- handler.PlatformView?.UpdateCanGoBackForward(virtualView);
+ platformView.UpdateCanGoBackForward(virtualView);
}
// https://stackoverflow.com/questions/37509990/migrating-from-uiwebview-to-wkwebview
@@ -87,9 +102,17 @@ public void DidFailProvisionalNavigation(WKWebView webView, WKNavigation navigat
public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action decisionHandler)
{
var handler = Handler;
+
+ if (handler is null || !handler.IsConnected())
+ {
+ decisionHandler.Invoke(WKNavigationActionPolicy.Cancel);
+ return;
+ }
+
+ var platformView = handler?.PlatformView;
var virtualView = handler?.VirtualView;
- if (handler == null || virtualView == null)
+ if (platformView is null || virtualView is null)
{
decisionHandler.Invoke(WKNavigationActionPolicy.Cancel);
return;
@@ -130,7 +153,7 @@ public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction,
var lastUrl = request.Url.ToString();
bool cancel = virtualView.Navigating(navEvent, lastUrl);
- handler.PlatformView?.UpdateCanGoBackForward(virtualView);
+ platformView.UpdateCanGoBackForward(virtualView);
decisionHandler(cancel ? WKNavigationActionPolicy.Cancel : WKNavigationActionPolicy.Allow);
}