3

各种 UIAppearance 代理实例不响应选择器(因为它们是其相关类型的代理,而不是它的实际实例),如本问答中所述。

这使得无法测试 Appearance API 的新 iOS 6 功能。例如,这种外观更改将永远不会执行,因为 if 检查中的代码总是返回 false,即使在 iOS 6 上也是如此,因为它正在检查的实例不是真实实例,而是外观代理。

if ( UINavigationBar.Appearance.RespondsToSelector( new Selector("setShadowImage:")))
    UINavigationBar.Appearance.ShadowImage = new UIImage();

链接的答案说使用该instancesRespondToSelector方法。但是我在 MT API 的任何地方都找不到它。我只是盲目,还是在 MT 中有不同的方法来实现这一点?

4

1 回答 1

4

和之间几乎没有区别,这里有一个很好的描述,只是后者是一种方法。respondsToSelector:instancesRespondToSelector:static

来自您的链接的答案用于真实instancesRespondToSelector:类型,而不是其代理。您可以使用MonoTouch 中已有的方法获得相同的结果。AppearanceRespondsToSelector

if (new UINavigationBar ().RespondsToSelector( new Selector("setShadowImage:")))
    UINavigationBar.Appearance.ShadowImage = new UIImage();

IOW 它假设如果setShadowImage:可用,那么您可以访问它的代理。对于以前存在的功能UIAppearance可用,情况并非如此(代码可能有效,但结果与您的期望不符)。

在 MT 中是否有不同的方法来实现这一点?

在许多情况下,您可以通过执行单个版本检查来启用/禁用多个功能,如下所示:

if (UIDevice.CurrentDevice.CheckSystemVersion (6,0)) {
    // enable iOS6 new features
} else {
    // fallback to iOS 5.x supported features
}

现在instancesRespondToSelector:不是 MonoTouch 提供的公共 API 的一部分(它需要在每种类型中绑定,至少在使用生成的绑定完成时)。但是,如果您愿意,实施起来并不难。您可以使用以下代码:

IntPtr responds_handle = Selector.GetHandle ("instancesRespondToSelector:");
IntPtr appearance_handle = new UINavigationBar ().ClassHandle; // *not* Handle
IntPtr setShadowImage_handle = Selector.GetHandle ("setShadowImage:");
bool result = Messaging.bool_objc_msgSend_IntPtr (appearance_handle, responds_handle, setShadowImage_handle);

如果你在几个地方需要它,你可以把它变成一个方法。请记住,它将返回与RespondsToSelector(针对您的特定问题)相同的答案。

于 2013-01-26T16:03:00.930 回答