如何在 iOS 扩展中使用 Xamarin Forms 全局样式

How to utilize Xamarin Forms Global Styles in iOS Extension

我的 Xamarin Forms 应用程序中有一个主题切换器,它使用一组静态资源文件效果很好。但是,我的应用程序也有一个 iOS 扩展,主题在那时就崩溃了。

在主应用程序中,我将主题分配给当前应用程序的资源 属性(即全局样式),所有视图都利用资源并在主题更改时自动更改。像这样:

Application.Current.Resources = new MyThemes.Default();

但是在扩展中,没有“应用程序”,因为页面只是直接添加到根 UIViewController。因此,我不能使用 Application.Current,它始终为 null。这些页面工作正常,但没有应用主题。如果我在创建它们时手动将它们分配给每个页面,我就可以使用这些主题,尽管它不像全局样式那样工作并且向下层叠到子页面。换句话说,像这样:

var myPage = new ContentPage();
myPage.Resources = new MyThemes.Default();
viewController = myPage.CreateViewController();

这可行,但并不完美,需要我重写当前由全局样式自动设置样式的部分共享视图。

我一直在四处寻找线索来正确地实现这一点,但没有任何运气,我觉得我遗漏了什么。我发现的所有内容似乎都只是从核心应用程序而不是扩展来谈论主题。

是否有关于在 Xamarin Forms iOS 扩展中使用主题资源和全局样式的文档或示例?感谢任何帮助,谢谢!

编辑:还值得注意的是,当自定义渲染器作为扩展加载时,自定义渲染器中对 Application.Current 的引用会导致静默崩溃。这可以通过使用 BindableProperty 来解决。

在花了一些时间研究这个问题之后,我找到了两个可能的解决方案。

使用助手 class 为创建子页面设置 Resources 即可获取当前主题。类似于:

var myPage = new Page()
{
     Resources = ThemeHelper.CurrentTheme()
});

您还可以在 Xamarin Forms 的 Init() 之后在您的扩展中手动创建应用程序,并在那里设置资源。虽然 Application 对象在技术上并不准确,但它似乎允许您按照预期的方式引用资源以达到样式化的目的。这实际上更好地实现了我的目标,但我还没有彻底测试过。 编辑:尽管这个解决方案很奇怪,但它似乎工作得很好并且完全解决了问题,而无需执行任何由扩展程序加载的特殊页面。

Application.Current = new Application();
Application.Current.Resources = ThemeHelper.CurrentTheme();

有趣的是,我确实偶然发现 an old bug post 指出 Page.CreateViewController() 使用 来设置 Application.Current。这可能会在没有任何特殊考虑的情况下解决我的问题,但它已被修补。

这两个似乎都很好,但我欢迎任何其他想法。