Skip to content

Remove Popup and ContentPage from LogicalChildren when Popup is closed on iOS#2166

Merged
bijington merged 5 commits into
CommunityToolkit:mainfrom
cat0363:Issue-2149
Sep 9, 2024
Merged

Remove Popup and ContentPage from LogicalChildren when Popup is closed on iOS#2166
bijington merged 5 commits into
CommunityToolkit:mainfrom
cat0363:Issue-2149

Conversation

@cat0363
Copy link
Copy Markdown
Contributor

@cat0363 cat0363 commented Sep 3, 2024

This PR resolves the issue where Popup and Content Page are not removed from LogicalChildren after closing Popup on iOS.

Description of Change

To accomplish this, first add MapOnClosed to the ControlPopUpCommandMapper.

[src\CommunityToolkit.Maui\HandlerImplementation\Popup\Popup.shared.cs]

	public static CommandMapper<IPopup, PopupHandler> ControlPopUpCommandMapper = new(PopupHandler.PopUpCommandMapper)
	{
#if IOS || MACCATALYST
		[nameof(IPopup.OnOpened)] = MapOnOpened,
		[nameof(IPopup.OnClosed)] = MapOnClosed
#endif
	};

Next, within the MapOnClosed method, remove Popup and ContentPage from LogicalChildren.

[src\CommunityToolkit.Maui\HandlerImplementation\Popup\Popup.macios.cs]

	public static void MapOnClosed(PopupHandler handler, IPopup view, object? result)
	{
		var parent = view.Parent as Element;
		if (parent is not null)
		{
			var contentPage = parent.LogicalChildrenInternal
				.Where(
					x => x is ContentPage
				)
				.LastOrDefault();

			var popup = parent.LogicalChildrenInternal
				.Where(
					x => x is Popup
				)
				.LastOrDefault();

			if (contentPage is not null)
			{
				parent.RemoveLogicalChild(contentPage);
			}
			if (popup is not null)
			{
				parent.RemoveLogicalChild(popup);
			}
		}
	}

Since Popup and ContentPage are stacked in LogicalChildren, remove the Popup and ContentPage added to LogicalChildren when the Popup was displayed last.

This will remove Popups and ContentPages from LogicalChildren in the order that Popups are closed.

Linked Issues

PR Checklist

Additional information

Below are the verification results.
For verification, I used the reproduction code of Issue #2149.

iPhone.15.iOS.17.0.2024-09-03.20-36-10.mp4

You can see that Popup and ContentPage are removed from LogicalChildren.

Next, I verified a pattern that displays popups hierarchically.

iPhone.15.iOS.17.0.2024-09-03.20-49-09.mp4

Similarly, you can see that Popup and ContentPage have been removed from LogicalChildren.

@cat0363 cat0363 changed the title Delete Popup and ContentPage from LogicalChildren when Popup is closed on iOS Remove Popup and ContentPage from LogicalChildren when Popup is closed on iOS Sep 3, 2024
Comment thread src/CommunityToolkit.Maui/HandlerImplementation/Popup/Popup.macios.cs Outdated
Copy link
Copy Markdown
Contributor

@bijington bijington left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @cat0363 this is great work as always

@bijington bijington merged commit ad1c25d into CommunityToolkit:main Sep 9, 2024
@cat0363
Copy link
Copy Markdown
Contributor Author

cat0363 commented Sep 12, 2024

@bijington , I found that the following code causes a problem in which Popup does not close when calling the CloseAsync or Close method of the Popup class.

[src\CommunityToolkit.Maui\HandlerImplementation\Popup\Popup.shared.cs]

	public static CommandMapper<IPopup, PopupHandler> ControlPopUpCommandMapper = new(PopupHandler.PopUpCommandMapper)
	{
#if IOS || MACCATALYST
		[nameof(IPopup.OnOpened)] = MapOnOpened,
		[nameof(IPopup.OnClosed)] = MapOnClosed        // <= here
#endif
	};

The above code prevents the following methods from being called.

[src\CommunityToolkit.Maui.Core\Handlers\Popup\PopupHandler.macios.cs]

	public static async void MapOnClosed(PopupHandler handler, IPopup view, object? result)
	{
		var presentationController = handler.PlatformView.PresentationController;
		if (presentationController?.PresentedViewController is UIViewController presentationViewController)
		{
			await presentationViewController.DismissViewControllerAsync(true);
		}

		view.HandlerCompleteTCS.TrySetResult();

		handler.DisconnectHandler(handler.PlatformView);
	}

I'm currently looking into how to fix it.

@cat0363
Copy link
Copy Markdown
Contributor Author

cat0363 commented Sep 12, 2024

@bijington , I have created a new PR #2202.
I apologize that this PR affected the closing of Pop Up by calling the Close or CloseAsync methods.

@github-actions github-actions Bot locked and limited conversation to collaborators Nov 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] iOS: Popup Remains in Page's LogicalChildren after Closing

3 participants