Skip to content

Commit

Permalink
Fix PopoverPresentationController for action sheet (#22312)
Browse files Browse the repository at this point in the history
* Fix PopoverPresentationController for action sheet

* - fix

* Fixed build error

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
  • Loading branch information
PureWeen and jsuarezruiz committed May 9, 2024
1 parent f76ea52 commit d88bb77
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 35 deletions.
Expand Up @@ -6,6 +6,8 @@
<VerticalStackLayout>
<Label Text="After clicking each button you should see an alert"></Label>
<Button Text="Open Alert With Modals" AutomationId="OpenAlertWithModals" Clicked="OpenAlertWithModals"></Button>
<Button Text="Open Action Sheet With Modals" AutomationId="OpenActionSheetWithModals" Clicked="OpenActionSheetWithModals"></Button>
<Button Text="Open Alert With New UIWindow" AutomationId="OpenAlertWithNewUIWindow" Clicked="OpenAlertWithNewUIWindow"></Button>
<Button Text="Open Action Sheet With New UIWindow" AutomationId="OpenActionSheetWithNewUIWindow" Clicked="OpenActionSheetWithNewUIWindow"></Button>
</VerticalStackLayout>
</ContentPage>
Expand Up @@ -4,6 +4,8 @@
using Microsoft.Maui;
using System.Linq;
using System;
using System.Threading.Tasks;


#if IOS
using UIKit;
Expand Down Expand Up @@ -38,8 +40,18 @@ async void OpenAlertWithModals(System.Object sender, System.EventArgs e)
await Navigation.PopModalAsync();
}

async void OpenActionSheetWithModals(System.Object sender, System.EventArgs e)
{
await Navigation.PushModalAsync(new ContentPage());
await Navigation.PushModalAsync(new ContentPage());
await this.DisplayActionSheet("hello", "message", "Cancel", "Option 1", "Option 2");
await Navigation.PopModalAsync();
await Navigation.PopModalAsync();
}

#if IOS
async void OpenAlertWithNewUIWindow(System.Object sender, System.EventArgs e)

async void OpenPrompt(System.Object sender, System.EventArgs e, Func<Page, Task> promptAction)
{
var uIWindow = new UIWindow();
var keyWindow = (this.Window.Handler.PlatformView as UIWindow);
Expand All @@ -59,7 +71,7 @@ async void OpenAlertWithNewUIWindow(System.Object sender, System.EventArgs e)
popupVC.ModalTransitionStyle = UIModalTransitionStyle.CoverVertical;
await uIWindow.RootViewController.PresentViewControllerAsync(popupVC, false);

await page.DisplayAlert("hello", "message", "Cancel");
await promptAction.Invoke(page);

var rvc = uIWindow.RootViewController;

Expand All @@ -74,11 +86,33 @@ async void OpenAlertWithNewUIWindow(System.Object sender, System.EventArgs e)
keyWindow.WindowLevel = UIWindowLevel.Normal;
this.RemoveLogicalChild(page);
}
#else
async void OpenAlertWithNewUIWindow(System.Object sender, System.EventArgs e)

void OpenAlertWithNewUIWindow(System.Object sender, System.EventArgs e)
{
OpenPrompt(sender, e, (page) =>
{
await this.DisplayAlert("hello", "message", "Cancel");
}
return page.DisplayAlert("hello", "message", "Cancel");
});
}


void OpenActionSheetWithNewUIWindow(System.Object sender, System.EventArgs e)
{
OpenPrompt(sender, e, (page) =>
{
return page.DisplayActionSheet("hello", "message", "Cancel", "Option 1", "Option 2");
});
}
#else
async void OpenActionSheetWithNewUIWindow(System.Object sender, System.EventArgs e)
{
await this.DisplayActionSheet("hello", "message", "Cancel", "Option 1", "Option 2");
}

async void OpenAlertWithNewUIWindow(System.Object sender, System.EventArgs e)
{
await this.DisplayAlert("hello", "message", "Cancel");
}
#endif
}
}
26 changes: 14 additions & 12 deletions src/Controls/src/Core/Platform/AlertManager/AlertManager.iOS.cs
Expand Up @@ -177,32 +177,34 @@ void PresentActionSheet(Page sender, ActionSheetArguments arguments)

static void PresentPopUp(Page sender, Window virtualView, UIWindow platformView, UIAlertController alert, ActionSheetArguments arguments = null)
{
UIWindow presentingWindow = platformView;

if (sender.Handler is IPlatformViewHandler pvh &&
pvh.PlatformView?.Window is UIWindow senderPageWindow &&
senderPageWindow != platformView &&
senderPageWindow.RootViewController is not null)
{
presentingWindow = senderPageWindow;
}

if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad && arguments != null)
{
var topViewController = GetTopUIViewController(presentingWindow);
UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications();
var observer = NSNotificationCenter.DefaultCenter.AddObserver(UIDevice.OrientationDidChangeNotification,
n => { alert.PopoverPresentationController.SourceRect = platformView.RootViewController.View.Bounds; });
n => { alert.PopoverPresentationController.SourceRect = topViewController.View.Bounds; });

arguments.Result.Task.ContinueWith(t =>
{
NSNotificationCenter.DefaultCenter.RemoveObserver(observer);
UIDevice.CurrentDevice.EndGeneratingDeviceOrientationNotifications();
}, TaskScheduler.FromCurrentSynchronizationContext());

alert.PopoverPresentationController.SourceView = platformView.RootViewController.View;
alert.PopoverPresentationController.SourceRect = platformView.RootViewController.View.Bounds;
alert.PopoverPresentationController.SourceView = topViewController.View;
alert.PopoverPresentationController.SourceRect = topViewController.View.Bounds;
alert.PopoverPresentationController.PermittedArrowDirections = 0; // No arrow
}

UIWindow presentingWindow = platformView;
if (sender.Handler is IPlatformViewHandler pvh &&
pvh.PlatformView?.Window is UIWindow senderPageWindow &&
senderPageWindow != platformView &&
senderPageWindow.RootViewController is not null)
{
presentingWindow = senderPageWindow;
}

presentingWindow.BeginInvokeOnMainThread(() =>
{
GetTopUIViewController(presentingWindow)
Expand Down
25 changes: 8 additions & 17 deletions src/Controls/tests/UITests/Tests/Issues/Issue16321.cs
Expand Up @@ -11,29 +11,20 @@ public class Issue16321 : _IssuesUITest
public override string Issue => "Alerts Open on top of current presented view";

[Test]
[TestCase("OpenAlertWithModals")]
[TestCase("OpenAlertWithNewUIWindow")]
[TestCase("OpenActionSheetWithNewUIWindow")]
[TestCase("OpenActionSheetWithModals")]
[Category(UITestCategories.DisplayAlert)]
public void OpenAlertWithModals()
public void OpenAlertWithModals(string testCase)
{
this.IgnoreIfPlatforms(new[]
{
TestDevice.Mac, TestDevice.Windows, TestDevice.Android
});

App.WaitForElement("OpenAlertWithModals").Click();
App.WaitForElement("Cancel").Click();
}

[Test]
[Category(UITestCategories.DisplayAlert)]
public void OpenAlertWithNewUIWindow()
{
this.IgnoreIfPlatforms(new[]
{
TestDevice.Mac, TestDevice.Windows, TestDevice.Android
});

App.WaitForElement("OpenAlertWithNewUIWindow").Click();
App.WaitForElement("Cancel").Click();
App.WaitForElement(testCase).Tap();
App.WaitForElement("Cancel").Tap();
}
}
}
}

0 comments on commit d88bb77

Please sign in to comment.