dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.27k stars 1.76k forks source link

[iOS] Application cannot be reset back to system theme #23411

Open filipnavara opened 4 months ago

filipnavara commented 4 months ago

Description

The accessor AppInfo.RequestedTheme returns an overridden theme once it's in effect and modal sheet is displayed:

https://github.com/dotnet/maui/blob/main/src/Essentials/src/AppInfo/AppInfo.ios.tvos.watchos.macos.cs#L58

It's used by Application class to set the value of PlatformAppTheme:

https://github.com/dotnet/maui/blob/main/src/Controls/src/Core/Application/Application.cs#L505

Once the theme is overridden once by setting Application.UserAppTheme to Light or Dark, the value of AppInfo.RequestedTheme sticks to the overridden trait for the current page (may be eventually reset on next page navigation due to how trait change events are propagated). This causes PlatformAppTheme to reflect the overridden value instead of the platform one, and setting Application.UserAppTheme = AppTheme.Unspecified no longer resets to the current OS default.

Steps to Reproduce

  1. [Have the iOS in Dark mode]
  2. Set Application.UserAppTheme = AppTheme.Light on startup
  3. Open modal sheet
  4. Set Application.UserAppTheme = AppTheme.Unspecifed on user action; observe no effect

With the repro project:

Note that the repro app changes the theme just fine from the main page, it's broken only when the modal page is shown. Only then AppInfo.RequestedTheme start returning the overridden value that is wrongly propagated to Application.PlatformAppTheme.

Link to public reproduction project repository

https://github.com/filipnavara/maui-dark-mode-ios-bug

Version with bug

8.0.61 SR6.1

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 17.5

Did you find any workaround?

No response

Relevant log output

No response

github-actions[bot] commented 4 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

filipnavara commented 4 months ago

Seems like UIScreen.MainScreen.TraitCollection always returns the non-overridden trait.

Current workaround:

    class AppInfoService : IAppInfo
    {
        private IAppInfo innerAppInfo;

        public AppInfoService()
        {
            innerAppInfo = (IAppInfo)Activator.CreateInstance(Type.GetType("Microsoft.Maui.ApplicationModel.AppInfoImplementation, Microsoft.Maui.Essentials"));
        }        

        public string PackageName => innerAppInfo.PackageName;

        public string Name => innerAppInfo.Name;

        public string VersionString => innerAppInfo.VersionString;

        public Version Version => innerAppInfo.Version;

        public string BuildString => innerAppInfo.BuildString;

        public AppTheme RequestedTheme
        {
            get
            {
                if ((OperatingSystem.IsIOS() && !OperatingSystem.IsIOSVersionAtLeast(13, 0)) || (OperatingSystem.IsTvOS() && !OperatingSystem.IsTvOSVersionAtLeast(13, 0)))
                    return AppTheme.Unspecified;

                var traits = UIScreen.MainScreen.TraitCollection;
                var uiStyle = traits.UserInterfaceStyle;

                return uiStyle switch
                {
                    UIUserInterfaceStyle.Light => AppTheme.Light,
                    UIUserInterfaceStyle.Dark => AppTheme.Dark,
                    _ => AppTheme.Unspecified
                };                
            }            
        }

        public AppPackagingModel PackagingModel => innerAppInfo.PackagingModel;

        public LayoutDirection RequestedLayoutDirection => innerAppInfo.RequestedLayoutDirection;

        public void ShowSettingsUI() => innerAppInfo.ShowSettingsUI();
    }
            typeof(AppInfo).GetMethod("SetCurrent", BindingFlags.NonPublic | BindingFlags.Static, new[] { typeof(IAppInfo) }).Invoke(
                null, new[] { new AppInfoService() });
ninachen03 commented 4 months ago

I can repro this issue at iOS platform on the latest 17.11.0 Preview 2.1(8.0.61 &8.0.60)

filipnavara commented 4 months ago

I can repro this issue at Android platform on the latest 17.11.0 Preview 2.1(8.0.61 &8.0.60)

I'm not sure if it has the same root cause then... this bug is specific to iOS. I'll check Android later on.

ninachen03 commented 4 months ago

My typo. I reproduced it on iOS. I updated my comment. Sorry for the inconvenience.

miko1258 commented 3 months ago

We can reproduce it on our iOS app as well

Alex-Dobrynin commented 1 month ago

When this will be fixed? the Application object does not react to system theme changes