Open petero-dk opened 9 years ago
Yes indeed for Mvvmcross plugins. I would also add a MvxModalPage that the presenter could assess in order to call PushModalAsync when appropriate!
What would be a good way to create a MvxModalPage?
The class would basically only serve as a "marker". Haven't tested the following but it's the basic idea. There are others ways of doing it but the iOS modal presenter uses this pattern.
class MvxModalPage : ContentPage
{
}
public abstract class MvxFormsPagePresenter
: MvxViewPresenter
{
private bool TryShowPage(MvxViewModelRequest request)
{
var page = MvxPresenterHelpers.CreatePage(request);
if (page == null)
return false;
var viewModel = MvxPresenterHelpers.LoadViewModel(request);
var mainPage = _mvxFormsApp.MainPage as NavigationPage;
page.BindingContext = viewModel;
if (mainPage == null)
{
_mvxFormsApp.MainPage = new NavigationPage(page);
mainPage = MvxFormsApp.MainPage as NavigationPage;
CustomPlatformInitialization(mainPage);
}
else
{
try
{
if (page is MvxModalPage)
{
mainPage.PushModalAsync(page);
}
else
{
// calling this sync blocks UI and never navigates hence code continues regardless here
mainPage.PushAsync(page);
}
}
catch (Exception e)
{
Mvx.Error("Exception pushing {0}: {1}\n{2}", page.GetType(), e.Message, e.StackTrace);
return false;
}
}
return true;
}
}
This is my "hackish" version for iOS but this should be adapted to be put in the shared presenter itself. Only PresentModalViewController is platform specific. It only supports 1 modal dialog at this point...
using MvvmCross.Core.ViewModels;
using MvvmCross.Forms.Presenter.Core;
using MvvmCross.Forms.Presenter.iOS;
using UIKit;
using Xamarin.Forms;
using Project.Views;
namespace Project.iOS
{
public class MvxModalFormsIosPagePresenter : MvxFormsIosPagePresenter
{
private UIWindow Window { get; set; }
public MvxModalFormsIosPagePresenter(UIWindow window, MvxFormsApp app) : base(window, app)
{
Window = window;
}
public override void Show(MvxViewModelRequest request)
{
NavigationPage mainPage = MvxFormsApp.MainPage as NavigationPage;
var page = MvxPresenterHelpers.CreatePage(request);
if (page != null && page.GetType().IsSubclassOf(typeof(ModalContentPage)) && mainPage != null)
{
page.BindingContext = MvxPresenterHelpers.LoadViewModel(request);;
mainPage.Navigation.PushModalAsync(page);
}
else
{
base.Show(request);
}
}
public override bool PresentModalViewController(UIViewController controller, bool animated)
{
Window.RootViewController.PresentViewController(controller, animated, null);
return true;
}
public override void ChangePresentation(MvxPresentationHint hint)
{
NavigationPage mainPage = MvxFormsApp.MainPage as NavigationPage;
if (mainPage != null && hint is MvxClosePresentationHint && mainPage.Navigation.ModalStack.Count > 0)
{
mainPage.Navigation.PopModalAsync(true);
}
else
{
base.ChangePresentation(hint);
}
}
}
}
On iOS the picture chooser plugin does not launch, this is because the picturechooser plugin relies on the PresentModalViewController which just returns false.
I propose that it be changed to: