Rg.Plugins.Popup icon indicating copy to clipboard operation
Rg.Plugins.Popup copied to clipboard

[Bug] XCT:StatusBarEffect.Color clashes with Rg:Plugins.Popup on iOS

Open maxchu92 opened this issue 2 years ago • 8 comments

Description

When replacing the Application.Current.MainPage with a page that has xct:StatusBarEffect.Color from a PopupPage, an error with RootViewController will occur on iOS. It was first occured to me when I was trying to reset the entire navigation stack, from a PopupPage, while I was navigating using Prism. _navigationService.NavigateAsync("/NavigationPage/MainPage");. I had reproduced this issue in both environment, Xamarin.Forms independently, and Xamarin.Forms + Prism.Forms. By changing the Application.Current.MainPage in a PopupPage, it will occur as well. This error will occur if I am trying to reset the navigation stack to a page with StatusBarEffect.

Exception

System.NullReferenceException: 'RootViewController'

Stack Trace

  at Xamarin.CommunityToolkit.iOS.Effects.PlatformStatusBarEffect.UpdateStatusBarAppearance (UIKit.UIWindow window) [0x00010] in <b86a3dcb5c1f42eeafd9e295123844ec>:0 
  at Xamarin.CommunityToolkit.iOS.Effects.PlatformStatusBarEffect.SetColor (Xamarin.Forms.Color color) [0x00079] in <b86a3dcb5c1f42eeafd9e295123844ec>:0 
  at Xamarin.CommunityToolkit.iOS.Effects.PlatformStatusBarEffect.OnAttached () [0x0000b] in <b86a3dcb5c1f42eeafd9e295123844ec>:0 
  at Xamarin.Forms.Effect.SendAttached () [0x00009] in D:\a\_work\1\s\Xamarin.Forms.Core\Effect.cs:54 
  at Xamarin.Forms.RoutingEffect.SendAttached () [0x00000] in D:\a\_work\1\s\Xamarin.Forms.Core\RoutingEffect.cs:29 
  at Xamarin.Forms.Element.AttachEffect (Xamarin.Forms.Effect effect) [0x00045] in D:\a\_work\1\s\Xamarin.Forms.Core\Element.cs:513 
  at Xamarin.Forms.Element.set_EffectControlProvider (Xamarin.Forms.IEffectControlProvider value) [0x0007c] in D:\a\_work\1\s\Xamarin.Forms.Core\Element.cs:238 
  at Xamarin.Forms.Platform.iOS.EffectUtilities.RegisterEffectControlProvider (Xamarin.Forms.IEffectControlProvider self, Xamarin.Forms.IElementController oldElement, Xamarin.Forms.IElementController newElement) [0x0001a] in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\EffectUtilities.cs:20 
  at Xamarin.Forms.Platform.iOS.PageRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00094] in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\PageRenderer.cs:141 
  at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00032] in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Platform.cs:240 
  at Xamarin.Forms.Platform.iOS.NavigationRenderer.CreateViewControllerForPage (Xamarin.Forms.Page page) [0x00008] in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\NavigationRenderer.cs:378 
  at Xamarin.Forms.Platform.iOS.NavigationRenderer.OnPushAsync (Xamarin.Forms.Page page, System.Boolean animated) [0x0001d] in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\NavigationRenderer.cs:353 
  at Xamarin.Forms.Platform.iOS.NavigationRenderer.<ViewDidLoad>b__47_0 (Xamarin.Forms.Page p) [0x00024] in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\NavigationRenderer.cs:239 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Users/builder/azdo/_work/2/s/xamarin-macios/src/Foundation/NSAction.cs:178 
--- End of stack trace from previous location where exception was thrown ---

  at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.Type principalClass, System.Type delegateClass) [0x0003b] in /Users/builder/azdo/_work/2/s/xamarin-macios/src/UIKit/UIApplication.cs:85 
  at XCTPopupStatusBarBugTest.iOS.Application.Main (System.String[] args) [0x00001] in C:\Users\DT005\source\repos\XCTPopupStatusBarBugTest\XCTPopupStatusBarBugTest\XCTPopupStatusBarBugTest.iOS\Main.cs:14 

Link to Reproduction Sample

  1. Xamarin.Forms Version

  2. Xamarin.Forms + Prism.Forms Version

Steps to Reproduce

  1. Run the app.
  2. Click on "Open Popup Page"
  3. Click on "Reset Stack" OR "Back to Root using Command"

Expected Behavior

Navigation stack is reset and go to MainPage without any error.

Actual Behavior

Error occurs when stack is reset.

Basic Information

  • Version with issue:

    • Xamarin.Forms v5.0.0.2401
    • Xamarin.CommunityToolkit v2.0.2
    • Rg.Plugin.Popup v2.1.0
    • Prism.DryIoc.Forms v8.1.97
    • Prism.Plugin.Popups v8.0.76
  • Last known good version:

  • IDE:

    • Visual Studio 2022
  • Platform Target Frameworks:

    • iOS: 15.4
  • Nuget Packages:

    • Xamarin.Essentials v1.7.3
    • Xamarin.Essentials.Interfaces v1.7.3

I had already create a bug report in XamarinCommunityToolkit repository as well.

maxchu92 avatar May 13 '22 09:05 maxchu92

hi @maxchu92

I looked through the issue on XamarinCommunityToolkit, and Pictos has reached out. I can give this a look about. Thankyou for the example :+1:

LuckyDucko avatar May 22 '22 06:05 LuckyDucko

hed out. I can give this a loo

Hi @LuckyDucko

Really appreciate the effort of you guys for checking this issue out! Thank you!

maxchu92 avatar May 23 '22 06:05 maxchu92

Has there been any progress on this issue? I've recently switched over to using Rg.Plugins.Popup because it's much easier to work without out of the box than the XCT popup, but we need to use StatusBarEffect.Color and these app crashes are a real problem.

nwilliams avatar Jul 09 '22 02:07 nwilliams

Sorry this went off my radar as i have been focusing on MAUI

I remember previously issues surrounding replacing the root navigation within a popup, some thoughts.

Does opening a modal, then a popup, THEN replacing Application.current.mainpage help dodge the issue?

Does the XCT matter in this scenario, or is it Application.Current.Mainpage?

i'll give this a whirl in the repo provided

LuckyDucko avatar Jul 09 '22 02:07 LuckyDucko

@LuckyDucko thanks for looking into this. The only place I'm actually running into this issue (so far) is when I chain popups. On a record details page, I have a "delete" button that, when pressed, opens a popup to confirm that the user actually wants to delete the record. If the user clicks the "Confirm" button, I close the popup, make an API call, and then open another popup that tells the user if the delete was successful or not. Everything works fine up to this point but closing the second popup causes the iOS app to crash on some devices.

nwilliams avatar Jul 12 '22 02:07 nwilliams

I faced the same problem. If I use Rg.Plugin.Popup, then after the Popup has been shown and closed. If you open Popup again or try to go to another screen, the application will crash.

[0:] An error occurred: 'RootViewController'. Callstack: '  at Xamarin.CommunityToolkit.iOS.Effects.PlatformStatusBarEffect.UpdateStatusBarAppearance (UIKit.UIWindow window) <0x135263840 + 0x00032> in <e29db44a5724499bb6d2544e250eefd7>:0 
  at Xamarin.CommunityToolkit.iOS.Effects.PlatformStatusBarEffect.SetColor (Xamarin.Forms.Color color) <0x135263028 + 0x0010e> in <e29db44a5724499bb6d2544e250eefd7>:0 
  at Xamarin.CommunityToolkit.iOS.Effects.PlatformStatusBarEffect.OnAttached () <0x135253a38 + 0x00014> in <e29db44a5724499bb6d2544e250eefd7>:0 
  at Xamarin.Forms.Effect.SendAttached () [0x00009] in D:\a\1\s\Xamarin.Forms.Core\Effect.cs:54 
  at Xamarin.Forms.RoutingEffect.SendAttached () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\RoutingEffect.cs:29 
  at Xamarin.Forms.Element.AttachEffect (Xamarin.Forms.Effect effect) [0x00045] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:513 
  at Xamarin.Forms.Element.set_EffectControlProvider (Xamarin.Forms.IEffectControlProvider value) [0x0007c] in D:\a\1\s\Xamarin.Forms.Core\Element.cs:238 
  at Xamarin.Forms.Platform.iOS.EffectUtilities.RegisterEffectControlProvider (Xamarin.Forms.IEffectControlProvider self, Xamarin.Forms.IElementController oldElement, Xamarin.Forms.IElementController newElement) [0x0001a] in D:\a\1\s\Xamarin.Forms.Platform.iOS\EffectUtilities.cs:20 
  at Xamarin.Forms.Platform.iOS.PageRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00094] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\PageRenderer.cs:141 
  at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00032] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Platform.cs:240 
  at Xamarin.Forms.Platform.iOS.NavigationRenderer.CreateViewControllerForPage (Xamarin.Forms.Page page) [0x00008] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\NavigationRenderer.cs:378 
  at Xamarin.Forms.Platform.iOS.NavigationRenderer.OnPushAsync (Xamarin.Forms.Page page, System.Boolean animated) [0x0001d] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\NavigationRenderer.cs:353 
  at Xamarin.Forms.NavigationPage.PushAsyncInner (Xamarin.Forms.Page page, System.Boolean animated) [0x00084] in D:\a\1\s\Xamarin.Forms.Core\NavigationPage.cs:452 
  at Xamarin.Forms.NavigationPage.PushAsync (Xamarin.Forms.Page page, System.Boolean animated) [0x0014e] in D:\a\1\s\Xamarin.Forms.Core\NavigationPage.cs:265 
  at MCS.BLEUpdater.UI.ViewModels.MainViewModel.NavigateToSettings () [0x0002a] in D:\Projects\MCS\MCS.BLEUpdater\MCS.BLEUpdater\MCS.BLEUpdater\UI\ViewModels\MainViewModel.cs:95 
  at CommunityToolkit.Mvvm.Input.AsyncRelayCommand.AwaitAndThrowIfFailed (System.Threading.Tasks.Task executionTask) [0x00016] in /_/src/CommunityToolkit.Mvvm/Input/AsyncRelayCommand.cs:351 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 
  at (wrapper delegate-invoke) <Module>.invoke_void_object(object)
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.18/src/Xamarin.iOS/Foundation/NSAction.cs:176 
--- End of stack trace from previous location where exception was thrown ---

  at (wrapper managed-to-native) UIKit.UIApplication.xamarin_UIApplicationMain(int,intptr,intptr,intptr,intptr&)
  at UIKit.UIApplication.UIApplicationMain (System.Int32 argc, System.String[] argv, System.IntPtr principalClassName, System.IntPtr delegateClassName) [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.18/src/Xamarin.iOS/UIKit/UIApplication.cs:58 
  at UIKit.UIApplication.Main (System.String[] args, System.Type principalClass, System.Type delegateClass) [0x0003b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.18/src/Xamarin.iOS/UIKit/UIApplication.cs:94 
  at MCS.BLEUpdater.iOS.Application.Main (System.String[] args) [0x00001] in D:\Projects\MCS\MCS.BLEUpdater\MCS.BLEUpdater\MCS.BLEUpdater.iOS\Main.cs:12 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:395 

vitalii-vov avatar Nov 17 '23 13:11 vitalii-vov

I found the reason that causes the application to crash. If the application supports a dark theme and has styles, then this leads to the application crashing when calling Popup on iOS.

If I comment out the code below in the App.xaml file, then the application works fine.

<Style TargetType="NavigationPage">
    <Setter Property="BarBackgroundColor" Value="{DynamicResource BarBackgroundColor}" />
    <Setter Property="BarTextColor" Value="{DynamicResource BarTextColor}" />

    <Setter Property="xct:StatusBarEffect.Color" Value="{DynamicResource BarBackgroundColor}" />
    <Setter Property="xct:StatusBarEffect.Style" Value="{AppThemeBinding Dark={x:Static xct:StatusBarStyle.LightContent}, Light={x:Static xct:StatusBarStyle.DarkContent}}" />
</Style>

<Style
    ApplyToDerivedTypes="True"
    TargetType="{x:Type ContentPage}">
    <Setter Property="BackgroundColor" Value="{DynamicResource AppBackgroundColor}" />
    <Setter Property="xct:StatusBarEffect.Color" Value="{DynamicResource BarBackgroundColor}" />
    <Setter Property="xct:StatusBarEffect.Style" Value="{AppThemeBinding Dark={x:Static xct:StatusBarStyle.LightContent}, Light={x:Static xct:StatusBarStyle.DarkContent}}" />
</Style>

Tested on iOS 17

vitalii-vov avatar Nov 17 '23 13:11 vitalii-vov

Could this line of code be the problem? Since here the RootViewController is simply replaced and after the Popup closed, does not change back.

https://github.com/rotorgames/Rg.Plugins.Popup/blob/8e5a1668c1aa990f21ad6dfb60db2caa36754df9/Rg.Plugins.Popup/Platforms/Ios/Impl/PopupPlatformIos.cs#L70

This could just lead to window?.RootViewController being null here

https://github.com/xamarin/XamarinCommunityToolkit/blob/5a6062f3c3543acda3c36ca4683cd8fc7fe86ba7/src/CommunityToolkit/Xamarin.CommunityToolkit/Effects/StatusBar/PlatformStatusBarEffect.ios.cs#L104

vitalii-vov avatar Nov 20 '23 13:11 vitalii-vov