1

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

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

应用看起来仍然很亮,但应该看起来很暗。

我意识到 AppDelegate 有一个 WillEnterForeground 方法,但我不知道如何将它连接起来,因此应用程序在前台看起来很暗。我正在使用 MvvmCross。以下链接看起来很有希望。

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

我不明白如何将链接的内容应用于我的 MvvmCross 架构。

感谢您的帮助!

谢谢!拉里

4

1 回答 1

3

在使用 MVVM 模式时对应用程序更改做出反应的最佳方法是实现一个IThemeService接口,如链接中所示。

xamarin 形成 iOS

但我认为在使用 MvvmCross 时无法对 Xamarin.Forms.iOS 平台中的配置更改做出反应。我查看了MvvmCross.Forms.iOS项目的源代码,找不到任何与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");
                }
            }
        }
    }

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

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

我从这个项目中复制了这段代码。

本机 xamarin iOS

当您使用本机 iOS 时,您可以覆盖该TraitCollectionDidChange方法。它相当于androidOnConfigurationChanged函数。Maybee在这里查看更多详细信息。我为您将 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 的实现代码。完成并改进一些事情,它会起作用。另请查看mvvmcross 示例 repo中的 StarWars 和 TipCalc 项目。

mvvmcross ioc

您的界面结构可能看起来像这样;IThemeService(基础项目)- ThemeService(基础项目)- ThemeService(iOS项目)

当然,您必须注册接口。

Mvx.IoCProvider.RegisterSingleton<IThemeService>(() => new ThemeService());
于 2020-12-28T16:59:16.953 回答