Reputation: 138
I want to avoid putting my OnBoarding
view in navigation stack to fix the problem of pressing the back button. In my MainPage
I check if OnBoarding
should appear or not. If true, I call PushModalAsync
method in OnAppearing
method. But the App crash with the following exception:
Objective-C exception thrown. Name: System.InvalidOperationException Reason: Window should have a UIWindow set. (System.InvalidOperationException)
at Microsoft.Maui.Controls.Window.get_NativeWindow()
at Microsoft.Maui.Controls.Platform.ModalNavigationManager.EndEditing()
at Microsoft.Maui.Controls.Platform.ModalNavigationManager.PushModalAsync(Page modal, Boolean animated)
at Microsoft.Maui.Controls.Window.NavigationImpl.OnPushModal(Page modal, Boolean animated)
at BytePesaApp.MainPage.OnAppearing() in MainPage.xaml.cs:line 18
at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
at Foundation.NSAsyncSynchronizationContextDispatcher.Apply()
Here is the code implementation:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
if (ShouldShowOnBoardingPage() == true)
{
await Navigation.PushModalAsync(new OnBoardingPage(), false);
}
}
private bool ShouldShowOnBoardingPage()
{
return VersionTracking.IsFirstLaunchEver;
}
}
Upvotes: 3
Views: 8220
Reputation: 21
one of the decisions is to use task:
protected override async void OnAppearing()
{
base.OnAppearing();
if (ShouldShowOnBoardingPage() == true)
{
Task.Run(async () =>
{
await Navigation.PushModalAsync(new OnBoardingPage(), false);
});
}
}
Upvotes: 2
Reputation: 29
The Loaded-Event is fired after OnAppearing()
; unfortunately, there is no OnLoad()
to override, so you have to use the event:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
this.Loaded += MainPage_Loaded;
}
protected async void MainPage_Loaded(object sender, EventArgs e)
{
if (ShouldShowOnBoardingPage() == true)
{
await Navigation.PushModalAsync(new OnBoardingPage(), false);
}
}
private bool ShouldShowOnBoardingPage()
{
return VersionTracking.IsFirstLaunchEver;
}
}
Upvotes: 3
Reputation: 21243
It sounds like Maui is not in a good state to navigate, until OnAppearing finishes. DEFER the navigation like this:
Dispatcher.Dispatch(async() =>
await Navigation.PushModalAsync(new OnBoardingPage(), false);
);
This code will be queued, and will run after OnAppearing returns.
An ALTERNATIVE is to replace the MainPage during OnBoarding.
In App.xaml.cs:
if (ShouldShowOnBoardingPage() == true)
MainPage = new OnBoardingPage();
else
MainPage = new MainPage();
Then when OnBoarding is complete:
Application.Current.MainPage = new MainPage();
I prefer the latter approach, if possible.
Upvotes: 4