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



这里有人(谢谢sushi宿醉!(帮助我的应用程序按命令读取iOS设置深色或浅色主题。我用的是Xamarin(不是Forms(。我还需要以下(仅适用于iOS(:

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

应用程序看起来仍然是浅色的,但应该是深色的。

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

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

我不知道如何将链接的内容应用到我的MvvmCross架构中。

感谢您的帮助!

谢谢!拉里

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

xamarin形成iOS

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

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

原生xamarin iOS

当您使用本机iOS时,您可以覆盖TraitCollectionDidChange方法。它相当于android的OnConfigurationChanged功能。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样本库中的《星球大战》和TipCalc项目。

mvvmcross-ioc

您的界面结构可能是这样的;IThemeService(基本项目(-主题服务(基础项目(-专题服务(iOS项目(

当然,你必须注册接口。

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

最新更新