在使用 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");
}
}
}
}
但是在AppDelegate
iOS 平台上,您没有任何这些功能可以覆盖。
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());