如何让 Xamarin iOS 应用程序自动感知明暗变化?

How can I Get Xamarin iOS Application to Automatically Sense Light and Dark Changes?

这里有人(感谢 sushihangover!)帮助我让我的应用程序根据命令读取 iOS 设置深色或浅色主题。我正在使用 Xamarin(不是表单)。我还需要以下内容(仅用于 iOS):

  1. iOS 设置主题为浅色
  2. 应用设置为自动,因此它使用当前的 iOS 设置主题(浅色)
  3. 启动的应用程序是 Light
  4. 主页按钮按下
  5. 将 iOS 设置更改为深色
  6. 将应用置于前台

应用看起来仍然是浅色,但它应该看起来是深色。

我知道 AppDelegate 有一个 WillEnterForeground 方法,但我不知道如何连接它,所以应用程序在前台时看起来很暗。我正在使用 MvvmCross。以下 link 看起来很有希望。

https://forums.xamarin.com/discussion/181648/best-approach-to-handle-dark-theme

我不明白如何将 link 的内容应用到我的 MvvmCross 架构中。

感谢您的帮助!

谢谢! 拉里

在使用 MVVM 模式时对应用程序更改做出反应的最佳方式是实现 IThemeService 接口,如 link.

中所示

xamarin 形式 iOS

但我认为在使用 MvvmCross 时无法对 Xamarin.Forms.iOS 平台中的配置更改做出反应。我查看了 MvvmCross.Forms.iOS project and couldn't find any equivalent to the MvvmCross.Forms.Android 设置方法的源代码,例如 OnConfigurationChanged.

在 Android 您可以在 MainActivity.

更改系统主题的同时轻松刷新应用程序主题
    public class MainActivity : MvxFormsAppCompatActivity
    {
        public override void OnConfigurationChanged(Configuration newConfig)
        {
            base.OnConfigurationChanged(newConfig);
            this.UpdateTheme(newConfig);
        }

        protected override void OnResume()
        {
            base.OnResume();
            UpdateTheme(Resources.Configuration);
        }

        protected override void OnStart()
        {
            base.OnStart();
            this.UpdateTheme(Resources.Configuration);
        }

        private void UpdateTheme(Configuration newConfig)
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Froyo)
            {
                var uiModeFlags = newConfig.UiMode & UiMode.NightMask;
                switch (uiModeFlags)
                {
                    case UiMode.NightYes:
                        Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Dark);
                        break;

                    case UiMode.NightNo:
                        Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Light);
                        break;

                    default:
                        throw new NotSupportedException($"UiMode {uiModeFlags} not supported");
                }
            }
        }
    }

但是在 iOS 平台上的 AppDelegate 中,您没有任何这些功能可以覆盖。

    public class AppDelegate : MvxFormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            return base.FinishedLaunching(application, launchOptions);
        }
    }

我从 project 复制了这段代码。

原生 xamarin iOS

当您使用本机 iOS 时,您可以覆盖 TraitCollectionDidChange 方法。它等同于 android OnConfigurationChanged 函数。 Maybee 查看 here 了解更多详情。我为您将 android 版本改编为 iOS。首先,您必须创建一个自定义视图控制器。

// your supported theme versions
 public enum BaseTheme
    {
        Inherit = 0,
        Light = 1,
        Dark = 2
    }

public class MyViewController : UIViewController
    {
        public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)
        {
            base.TraitCollectionDidChange(previousTraitCollection);

            if (TraitCollection.UserInterfaceStyle != previousTraitCollection.UserInterfaceStyle)
            {
                UpdateTheme(TraitCollection.UserInterfaceStyle);
            }
               
        }

        private void UpdateTheme(UIUserInterfaceStyle newConfig)
        {
            switch(newConfig)
            {
                case UIUserInterfaceStyle.Dark:
                    Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Dark);
                    break;

                case UIUserInterfaceStyle.Light:
                    Mvx.IoCProvider.Resolve<IThemeService>().UpdateTheme(BaseTheme.Light);
                    break;

                default:
                    throw new NotSupportedException($"UiMode {uiModeFlags} not supported");
            }      
        }
    }

我上传了一个项目,我在其中简化了原生 IOS 和 android here. Complete and improve some things and it will work. Also look at the StarWars and TipCalc Project in the mvvmcross sample repo.

的代码实现

mvvmcross ioc

你的界面结构可能是这样的; IThemeService(基础项目)- ThemeService(基础项目)- ThemeService(iOS 项目)

而且你当然要注册接口。

Mvx.IoCProvider.RegisterSingleton<IThemeService>(() => new ThemeService());