[BUG] Crash occurs when a page transition occurs while displaying a Snackbar with an anchor specified on iOS
Is there an existing issue for this?
- [x] I have searched the existing issues
Did you read the "Reporting a bug" section on Contributing file?
- [x] I have read the "Reporting a bug" section on Contributing file: https://github.com/CommunityToolkit/Maui/blob/main/CONTRIBUTING.md#reporting-a-bug
Current Behavior
The app will crash if a page transition occurs while displaying a Snackbar with an anchor specified. This issue only occurs on iOS and not on Android.
Expected Behavior
Even if a page transition occurs while displaying a Snackbar with an anchor specified, the app will continue to operate without crashing.
Steps To Reproduce
- Press the Next Page Button.
- Press the Show Snackbar Button.
- Press the Back Pag Button.
Step 3 should be performed while the snack bar displayed in step 2 is displayed. The application crashes at step 3.
Link to public reproduction project repository
https://github.com/cat0363/MauiComm-IssueSnackbarCrash.git
Environment
- .NET MAUI CommunityToolkit: 12.1.0
- OS: iOS 17.0
- .NET MAUI: 9.0.90
Anything else?
Below is the debug log.
ObjCRuntime.ObjCException: 'Objective-C exception thrown. Name: NSGenericException Reason: Unable to activate constraint with anchors <NSLayoutYAxisAnchor:0x600001778d00 "UILayoutGuide:0x600003b3c8c0'UIViewSafeAreaLayoutGuide'.bottom"> and <NSLayoutYAxisAnchor:0x600001755b00 "UILayoutGuide:0x600003b44c40'UIViewSafeAreaLayoutGuide'.top"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal. Native stack trace: 0 CoreFoundation 0x000000018048d8a8 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x000000018008409c objc_exception_throw + 56 2 CoreAutoLayout 0x00000001ca3c4430 -[NSLayoutConstraint setActive:] + 0 3 libxamarin-dotnet-debug.dylib 0x00000001038f4ef8 xamarin_dyn_objc_msgSend + 160 4 MauiComm-IssueSnackbarCrash 0x0000000102e7189c interp_to_native_trampoline + 172 5 libmonosgen-2.0.dylib 0x0000000103c49c6c ves_pinvoke_method + 584 6 libmonosgen-2.0.dylib 0x0000000103c3e408 mono_interp_exec_method + 2936 7 libmonosgen-2.0.dylib 0x0000000103c3be60 interp_runtime_invoke + 244 8 libmonosgen-2.0.dylib 0x0000000103b57954 mono_jit_runtime_invoke + 1244 9 libmonosgen-2.0.dylib 0x0000000103d15e40 mono_runtime_invoke_checked + 148 10 libmonosgen-2.0.dylib 0x0000000103d19a18 mono_runtime_invoke + 540 11 libxamarin-dotnet-debug.dylib 0x00000001038ec0a0 xamarin_invoke_trampoline + 5424 12 libxamarin-dotnet-debug.dylib 0x00000001038f3bd0 xamarin_arch_trampoline + 148 13 libxamarin-dotnet-debug.dylib 0x00000001038f4dcc xamarin_arm64_common_trampoline + 64 14 UIKitCore 0x00000001857cdb1c -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1492 15 QuartzCore 0x0000000189f6fdd4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 440 16 QuartzCore 0x0000000189f7ab30 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 124 17 QuartzCore 0x0000000189e963bc _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 460 18 QuartzCore 0x0000000189ec5bf0 _ZN2CA11Transaction6commitEv + 652 19 QuartzCore 0x0000000189ec70a4 _ZN2CA11Transaction25flush_as_runloop_observerEb + 68 20 CoreFoundation 0x00000001803ed648 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 32 21 CoreFoundation 0x00000001803e804c __CFRunLoopDoObservers + 528 22 CoreFoundation 0x00000001803e8504 __CFRunLoopRun + 968 23 CoreFoundation 0x00000001803e7d28 CFRunLoopRunSpecific + 572 24 GraphicsServices 0x000000018e7cdbc0 GSEventRunModal + 160 25 UIKitCore 0x00000001852bafdc -[UIApplication _run] + 868 26 UIKitCore 0x00000001852bec54 UIApplicationMain + 124 27 libxamarin-dotnet-debug.dylib 0x00000001038a5a94 xamarin_UIApplicationMain + 60 28 libmonosgen-2.0.dylib 0x0000000103c4b3b0 do_icall + 316 29 libmonosgen-2.0.dylib 0x0000000103c498d4 do_icall_wrapper + 356 30 libmonosgen-2.0.dylib 0x0000000103c3e228 mono_interp_exec_method + 2456 31 libmonosgen-2.0.dylib 0x0000000103c3be60 interp_runtime_invoke + 244 32 libmonosgen-2.0.dylib 0x0000000103b57954 mono_jit_runtime_invoke + 1244 33 libmonosgen-2.0.dylib 0x0000000103d15e40 mono_runtime_invoke_checked + 148 34 libmonosgen-2.0.dylib 0x0000000103d1d0a0 mono_runtime_exec_main_checked + 116 35 libmonosgen-2.0.dylib 0x0000000103baaa40 mono_jit_exec + 364 36 libxamarin-dotnet-debug.dylib 0x00000001038f3a6c xamarin_main + 2028 37 MauiComm-IssueSnackbarCrash 0x0000000102e890d0 main + 64 38 dyld 0x0000000103109558 start_sim + 20 39 ??? 0x0000000102ed2274 0x0 + 4344062580
The only workaround is to keep an instance of Snackbar around and call the Dismiss method in the OnNavigatingFrom event.
private ISnackbar snackbar;
private void btnShow_Clicked(object sender, EventArgs e)
{
snackbar = Snackbar.Make("This is test message.", null, string.Empty, new TimeSpan(0, 0, 0, 0, 3000), new CommunityToolkit.Maui.Core.SnackbarOptions() { BackgroundColor = Colors.Green, TextColor = Colors.White }, gdSnackBarAnchor);
snackbar.Show();
}
private void btnBack_Clicked(object sender, EventArgs e)
{
Shell.Current.Navigation.PopAsync(false);
}
protected async override void OnNavigatingFrom(NavigatingFromEventArgs args)
{
if (snackbar is not null)
{
await snackbar.Dismiss();
}
base.OnNavigatingFrom(args);
}
At the very least, any currently displayed Snackbars will be forcibly closed, but this will prevent the app from crashing when switching between screens.