Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix. ModalControllerDelegate.WillDismiss() closes a ViewController when the ViewController is not actually dismissed by a user #4785

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 14 additions & 13 deletions MvvmCross/Platforms/Ios/Presenters/MvxIosViewPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ private Task<bool> ShowPopoverViewControllerChild(UIViewController viewControlle

viewController.ModalPresentationStyle = attribute.ModalPresentationStyle;
viewController.ModalTransitionStyle = attribute.ModalTransitionStyle;
if (attribute.PreferredContentSize != default(CGSize))
if (attribute.PreferredContentSize != default)
viewController.PreferredContentSize = attribute.PreferredContentSize;

if (_iosVersion13Checker.IsVersionOrHigher && viewController.PresentationController != null)
Expand All @@ -427,10 +427,8 @@ private Task<bool> ShowPopoverViewControllerChild(UIViewController viewControlle
new MvxModalPresentationControllerDelegate(this, viewController, attribute);
}

// Check if there is a modal already presented first. Otherwise use the window root
var modalHost = ModalViewControllers.LastOrDefault() ?? Window.RootViewController;

modalHost.PresentViewController(viewController, attribute.Animated, null);
var parentViewController = GetParentViewController();
parentViewController.PresentViewController(viewController, attribute.Animated, null);

ModalViewControllers.Add(viewController);

Expand Down Expand Up @@ -459,11 +457,6 @@ private Task<bool> ShowPopoverViewControllerChild(UIViewController viewControlle
viewController = CreateNavigationController(viewController);
}

// Check if there is a modal already presented first. Otherwise use the topmost view controller.
var viewHost = ModalViewControllers.LastOrDefault() ?? Window.RootViewController;
if (viewHost == null)
throw new MvxException($"Trying to show View type: {viewController.GetType().Name} as popover, but could not find a view host!");

viewController.ModalPresentationStyle = UIModalPresentationStyle.Popover;

var presentationController = viewController.PopoverPresentationController;
Expand All @@ -474,10 +467,19 @@ private Task<bool> ShowPopoverViewControllerChild(UIViewController viewControlle
presentationController.Delegate = new MvxPopoverPresentationControllerDelegate(this);

PopoverViewController = viewController;
await viewHost.PresentViewControllerAsync(viewController, attribute.Animated).ConfigureAwait(true);

var parentViewController = GetParentViewController();
await parentViewController.PresentViewControllerAsync(viewController, attribute.Animated).ConfigureAwait(true);
return true;
}

private UIViewController GetParentViewController()
evgenyvalavin marked this conversation as resolved.
Show resolved Hide resolved
{
//Ensure to get a ViewController that is not being dismissed. See related bugs https://github.com/MvvmCross/MvvmCross/issues/4781
return ModalViewControllers.LastOrDefault(x => !x.IsBeingDismissed) ?? Window.RootViewController
?? throw new MvxException($"No parent ViewController found.");
}

protected virtual Task<bool> ShowMasterSplitViewController(
UIViewController viewController,
MvxSplitViewPresentationAttribute attribute,
Expand Down Expand Up @@ -726,8 +728,7 @@ protected virtual void CloseMasterNavigationController()
MasterNavigationController = null;
}

public virtual async Task<bool> CloseModalViewController(
UIViewController viewController, MvxModalPresentationAttribute attribute)
public virtual async Task<bool> CloseModalViewController(UIViewController viewController, MvxModalPresentationAttribute attribute)
{
ValidateArguments(viewController, attribute);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@
// See the LICENSE file in the project root for more information.

using MvvmCross.Platforms.Ios.Presenters.Attributes;
using UIKit;

namespace MvvmCross.Platforms.Ios.Presenters
namespace MvvmCross.Platforms.Ios.Presenters;

public class MvxModalPresentationControllerDelegate : UIAdaptivePresentationControllerDelegate
{
public class MvxModalPresentationControllerDelegate : UIAdaptivePresentationControllerDelegate
{
private readonly MvxIosViewPresenter _presenter;
private readonly UIViewController _viewController;
private readonly MvxModalPresentationAttribute _attribute;
private readonly MvxIosViewPresenter _presenter;
private readonly UIViewController _viewController;
private readonly MvxModalPresentationAttribute _attribute;

public MvxModalPresentationControllerDelegate(MvxIosViewPresenter presenter, UIViewController viewController, MvxModalPresentationAttribute attribute)
{
_presenter = presenter;
_viewController = viewController;
_attribute = attribute;
}
public MvxModalPresentationControllerDelegate(MvxIosViewPresenter presenter, UIViewController viewController, MvxModalPresentationAttribute attribute)
{
_presenter = presenter;
_viewController = viewController;
_attribute = attribute;
}

public override void WillDismiss(UIPresentationController presentationController)
{
_presenter.CloseModalViewController(_viewController, _attribute);
}
public override async void DidDismiss(UIPresentationController presentationController)
{
await _presenter.CloseModalViewController(_viewController, _attribute).ConfigureAwait(false);
}
}
}