Xamarin.forms: [Bug] Shell - Go back two pages crashes the app with a NullReferenceException

Created on 11 Jun 2019  路  21Comments  路  Source: xamarin/Xamarin.Forms

Description

Shell does not support the ability to navigate back more than one page at a time.

Steps to Reproduce

  1. Navigate three pages deep.
  2. Remove one page from the NavigationStack
  3. PopAsync to go back

Expected Behavior

Navigates back two pages. It worked this way for Xamarin Forms Navigation before.
https://stackoverflow.com/questions/24856116/how-to-popasync-more-than-1-page-in-xamarin-forms-navigation

Actual Behavior

Throws null reference exception from Shell.GetNavBarIsVisible.
Object reference not set to an instance of an object
Source: Xamarin.Forms.Core
at Xamarin.Forms.Shell.GetNavBarIsVisible (Xamarin.Forms.BindableObject obj) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Shell\Shell.cs:69
at Xamarin.Forms.Platform.iOS.ShellSectionRenderer+NavDelegate.WillShowViewController (UIKit.UINavigationController navigationController, UIKit.UIViewController viewController, System.Boolean animated) [0x00028] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellSectionRenderer.cs:469
at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.10.0.153/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.10.0.153/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at CommonAlly.iOS.Application.Main (System.String[] args) [0x00001] in C:\Users\seans\source\commonally-mobile\CommonAlly\CommonAlly.iOS\Main.cs:17

Basic Information

  • Version with issue: 4.0.0.482894
  • Last known good version: N/A
  • IDE: Visual Studio 2019 for Windows 16.1.2
  • Platform Target Frameworks:

    • iOS: 12.10.0.153

    • Android: N/A

    • UWP: N/A

  • Android Support Library Version: N/A
  • Nuget Packages: Just what comes with the template
  • Affected Devices:

Screenshots

Reproduction Link

https://github.com/seansparkman/ShellNavigationExample
https://github.com/seansparkman/ShellNavigationExample/blob/master/ShellNavigationRegistration/ShellNavigationRegistration/Views/OnBoardingThird.xaml.cs

shell 2 high in-progress bug

All 21 comments

So I tried using two PopAsync calls instead, and that just results in a black screen. The OnAppearing event triggers correctly, but the screen disappears.
https://github.com/seansparkman/ShellNavigationExample/blob/double-popasync/ShellNavigationRegistration/ShellNavigationRegistration/Views/OnBoardingThird.xaml.cs#L27-L28

The weird thing is, if you inspect the NavigationStack you will see that the 0 index is actually a null value. That might have something to do with this?

That's pretty weird. Also why would it be looking at the 0 index if I only pop back two places? There are four items in the NavigationStack before I RemovePage.

I think you are missing a step? The NavigationPage constructor calls PushPage. https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Core/NavigationPage.cs#L430-L438

I'm facing the same issue here, is there any work around for this?

I could see there being a bug on the platforms not correctly syncing internal collections if pages are removed or popped quickly like that

https://github.com/seansparkman/ShellNavigationExample/blob/master/ShellNavigationRegistration/ShellNavigationRegistration/Views/OnBoardingThird.xaml.cs#L22

Double popping sequentially I could see there possibly being a timing issue here. Not ideal but if you put the second one inside a Device.BeginInvoke does that work?

We'll need to test through more of the removepage and sequential popping scenarios.

The null entry on the Navigation stack represents the "shellcontent" so it's not really a page on the stack since it's the root container.

This was a recent thing I discovered as well when getting Shell fixed up to be more MVVM friendly. I'm not really a fan of that null element at index 0. That root element should just be the page that's renderered in the shell content not a null value.

at Xamarin.Forms.Shell.GetNavBarIsVisible (Xamarin.Forms.BindableObject obj) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Shell\Shell.cs:69

tells me that it's a timing issue with double popping like that. That it starts popping the second page but aspects of that first pop haven't resolved yet. The changes to add more hooks with NavigationHandler is going to bring about the age of better pipelines for these things so that resolution happens before popping.

Ideally you wouldn't have to double pop and just remove pages but that'll need to be looked at

Any update on this ? Or is there any workaround for this scenario ?

I found that turning animation off is a workaround, i.e:

await Shell.Current.Navigation.PopAsync(animated: false);

If you must have animation, adding Task.Delays of ~500 ms also worked. But I like the approach of turning animation off better.

Hmm, with Xamarin.Forms 4.3.0.947036 the workaround with animated: false is no longer enough. Adding a Delay of 500 ms is still working, though.

According to some google results, it seems that Calling ViewControllers.Remove method doesn't affect the original ViewControllers since it's immutable. Instead it should be replaced by a new array. Same to ViewControllers.Insert when calling InsertPageBefore.

EDIT:
sorry didn't notice the assignment in remove, but it's still an issue with insert.

Any Fix this. I have same issue.please

I'm hitting this too - any idea when it might get looked at, please?

If this helps for correcting the problem which is iOS specific: it seems it is located in Xamarin.Forms.ShellSection.OnRemovePage(Page page) function. The current code is:

RemovePage(page);
var args = new NavigationRequestedEventArgs(page, false)
{
RequestType = NavigationRequestType.Remove
};
_navigationRequested?.Invoke(this, args);

But RemovePage should be after _navigationRequested?.Invoke, otherwise the iOS ShellSectionRenderer.OnRemoveRequested function will be unable to retrieve the page renderer to remove the corresponding UIViewController from the native navigation stack.

This problem has gotten worse for Xamarin.Forms 4.4.0.991265, now the delay and disabling animations does not help anymore causing the iOS app to crash with NullReferenceException with the same stack trace outlined above.

Having read the above comment, I have just tested with Xamarin.Forms 4.5 release version (4.5.0.356) and to my pleasant surprise, it seems to have gone away in that. In my code, it now works with and without animation and with no delays added 馃槉. I tested in both simulator and on a real device.

I just tested as well with Xamarin.Forms 4.5.0.356 and it causes the same problem with my code. (NullReferenceException). No surprise as the involved Xamarin.Forms source code (ShellSection and iOS ShellSectionRenderer) has not changed.

as i know this issue has been fixed and merged to master, but when we has an release?

It's merged into 4.5 so it should be part of the upcoming 4.5 service release which _should_ land somewhere next week! By that time please let us know if that fixes it for you, thanks!

It's merged into 4.5 so it should be part of the upcoming 4.5 service release which _should_ land somewhere next week! By that time please let us know if that fixes it for you, thanks!

It's work on v4.5.0.617, thanks

Yes it works now with 4.5.0.617 !

Great! Thank you for letting us know :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jgold6 picture jgold6  路  3Comments

simontocknell picture simontocknell  路  3Comments

deakjahn picture deakjahn  路  3Comments

xabre picture xabre  路  3Comments

EmilAlipiev picture EmilAlipiev  路  3Comments