Skip to content

[BUG] CloseOnBackground not honored on iOS #3403

Description

@fcjoe-gis

Description

Title: IDialogService popup with CloseOnBackgroundTapped="True" does not dismiss on iOS (Mopups container missing the dismiss mask)


This is the iOS counterpart to #3322 ("CloseOnBackgroundTapped not honored"),
which was closed as fixed on the private feed. On Prism.Plugin.Popups.Maui
9.1.33-pre the flag is now plumbed correctly, but the popup still does not
dismiss on background tap on iOS. I traced it to the container layout.

Environment

  • Prism.DryIoc.Maui 9.1.111-pre, Prism.Maui 9.1.86-pre
  • Prism.Plugin.Popups.Maui 9.1.33-pre, Mopups 1.3.4
  • .NET 10, net10.0-ios, iOS 26 simulator + device

Root cause

The flag is read and applied — Prism.Maui's DialogServiceBase reads
DialogLayout.GetCloseOnBackgroundTapped(view) and passes it to
PopupDialogContainer.ConfigureLayout, which sets
((PopupPage)this).CloseWhenBackgroundIsClicked = hideOnBackgroundTapped.

The problem is the layout. PopupDialogContainer.GetContentLayout builds a
screen-filling AbsoluteLayout with the dialog as a centered child, then
leans on Mopups' CloseWhenBackgroundIsClicked to detect a background tap. But
that mechanism only fires for a tap outside the content frame — and the
AbsoluteLayout fills the whole page, so on iOS every tap is "inside content"
and the background tap is never recognized.

By contrast, Prism.Maui's default container DialogContainerPage does not
rely on Mopups detection — it adds a BoxView mask with a
TapGestureRecognizer bound to the dismiss command. PopupDialogContainer is
simply missing that mask.

Suggested fix

Give PopupDialogContainer the same mask + gesture that DialogContainerPage
already uses, instead of depending on CloseWhenBackgroundIsClicked. A minimal
override that does exactly this (drop-in proof, in the repro):

protected override View GetContentLayout(Page currentPage, View dialogView,
    bool hideOnBackgroundTapped, ICommand dismissCommand, IDialogParameters parameters)
{
    var content = base.GetContentLayout(currentPage, dialogView, hideOnBackgroundTapped,
        dismissCommand, parameters);

    if (hideOnBackgroundTapped && content is AbsoluteLayout layout)
    {
        var scrim = new BoxView { Color = Colors.Transparent };
        AbsoluteLayout.SetLayoutFlags(scrim, AbsoluteLayoutFlags.All);
        AbsoluteLayout.SetLayoutBounds(scrim, new Rect(0, 0, 1, 1));
        scrim.GestureRecognizers.Add(new TapGestureRecognizer { Command = dismissCommand });
        layout.Children.Insert(0, scrim); // behind the dialog
    }

    return content;
}

Steps to Reproduce

Repro

Minimal repo: [prism-popup-dismiss-repro]

  1. UsePrism(... .ConfigureMopupDialogs() ...), register a dialog whose root sets
    prism:DialogLayout.CloseOnBackgroundTapped="True".
  2. IDialogService.ShowDialog(...) it on iOS.
  3. Tap the dimmed background.

Expected: dialog dismisses. Actual: dialog stays open.

Platform with bug

.NET MAUI

Affected platforms

iOS

Did you find any workaround?

No response

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions