Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue20612.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using Microsoft.Maui.Maps;

namespace Maui.Controls.Sample.Issues;

[Issue(IssueTracker.Github, 20612, "Disconnecting Map Handler causes Map to crash on second page entrance and moving to region.", PlatformAffected.iOS | PlatformAffected.macOS)]
public class Issue20612 : TestNavigationPage
{
protected override void Init()
{
PushAsync(new Issue20612page1());
}
}

public class Issue20612page1 : ContentPage
{
public Issue20612page1()
{
var openMapButton = new Button
{
Text = "Navigate to Map page",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
AutomationId = "MapButton"
};

openMapButton.Clicked += (s, e) =>
{
Navigation.PushAsync(new Issue20612page2());
};
Content = openMapButton;
}
}

public class Issue20612page2 : ContentPage
{
private Microsoft.Maui.Controls.Maps.Map _map;

public Issue20612page2()
{
_map = new Microsoft.Maui.Controls.Maps.Map
{
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
BackgroundColor = Colors.Red
};

var goBackButton = new Button
{
Text = "Go back",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
AutomationId = "GoBackButton"
};
goBackButton.Clicked += GoBack;

var grid = new Grid
{
RowDefinitions =
{
new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }, // Row 0: for map
new RowDefinition { Height = GridLength.Auto } // Row 1: for button
}
};

grid.Children.Add(_map);
Grid.SetRow(_map, 0);

grid.Children.Add(goBackButton);
Grid.SetRow(goBackButton, 1);
Content = grid;

MoveMap();
}

private async void MoveMap()
{
await Task.Delay(1000).ConfigureAwait(false);

MainThread.BeginInvokeOnMainThread(() =>
{
var mapSpan = MapSpan.FromCenterAndRadius(
new Location(5, 5),
Distance.FromMeters(10000));

_map.MoveToRegion(mapSpan);
});
}

void GoBack(object sender, EventArgs e)
{
_map.Handler?.DisconnectHandler();
Navigation.PopAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#if TEST_FAILS_ON_WINDOWS
//No Map control support in windows https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/map?view=net-maui-9.0
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;
public class Issue20612 : _IssuesUITest
{
public Issue20612(TestDevice device) : base(device) { }

public override string Issue => "Disconnecting Map Handler causes Map to crash on second page entrance and moving to region.";

[Test]
[Category(UITestCategories.Maps)]
public void MapsShouldNotCrashWhenNavigationOccurs()
{
App.WaitForElement("MapButton");
App.Tap("MapButton");
App.WaitForElement("GoBackButton");
App.Tap("GoBackButton");
// second Navigation to Map page
App.WaitForElement("MapButton");
App.Tap("MapButton");
}
}
#endif
2 changes: 1 addition & 1 deletion src/Core/maps/src/Handlers/Map/MapHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class MapHandler : ViewHandler<IMap, MauiMKMapView>

protected override MauiMKMapView CreatePlatformView()
{
return MapPool.Get() ?? new MauiMKMapView(this);
return MapPool.Get(this) ?? new MauiMKMapView(this);
}

protected override void ConnectHandler(MauiMKMapView platformView)
Expand Down
11 changes: 10 additions & 1 deletion src/Core/maps/src/Platform/iOS/MapPool.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using Microsoft.Maui.Maps.Handlers;

namespace Microsoft.Maui.Maps.Platform
{
Expand All @@ -11,6 +12,14 @@ internal class MapPool

public static void Add(MauiMKMapView mapView) => Instance.Maps.Enqueue(mapView);

public static MauiMKMapView? Get() => Instance.Maps.TryDequeue(out MauiMKMapView? mapView) ? mapView : null;
public static MauiMKMapView? Get(IMapHandler mapHandler)
{
if (Instance.Maps.TryDequeue(out MauiMKMapView? mapView) && mapView is not null)
{
mapView.Handler = mapHandler;
return mapView;
}
return null;
}
}
}
16 changes: 16 additions & 0 deletions src/Core/maps/src/Platform/iOS/MauiMKMapView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@ public MauiMKMapView(IMapHandler handler)
OverlayRenderer = GetViewForOverlayDelegate;
}

internal IMapHandler? Handler
{
get
{
_handlerRef.TryGetTarget(out var handler);
return handler;
}
set
{
if (value is not null)
{
_handlerRef = new WeakReference<IMapHandler>(value);
}
}
}

public override void MovedToWindow()
{
base.MovedToWindow();
Expand Down
Loading