【问题标题】:How can I Get Xamarin iOS Application to Automatically Sense Light and Dark Changes?如何让 Xamarin iOS 应用程序自动感知明暗变化?
【发布时间】:2023-03-23 06:06:02
【问题描述】:

这里有人(感谢 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 架构。

感谢您的帮助!

谢谢! 拉里

【问题讨论】:

    标签: ios xamarin mvvmcross darkmode


    【解决方案1】:

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

    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");
                    }
                }
            }
        }
    

    但在 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函数。 更多详情,请查看 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 的编码实现。完成并改进一些事情,它会起作用。另请查看mvvmcross sample repo 中的 StarWars 和 TipCalc 项目。

    mvvmcross ioc

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

    而且你当然要注册接口。

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

    【讨论】:

    • 嗨!感谢您的答复。我正在使用 Xamarin,但不是 Xamarin Forms。我会更新说明。您的建议可以针对我的架构量身定制吗?我不知道怎么做。谢谢!
    • 我更新了答案,希望你能找到正确的方法。
    • 我现在正在处理它。如果不违反 SO 政策,您可以发送电子邮件至 lfeldman65@gmail.com 或给我您的电子邮件地址吗?
    • 如果你愿意,我可以在我的 GitHub 上上传一个示例 repo
    • 那太好了。谢谢!
    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多