MonoTouch instancesRespondToSelector实现在哪里?

时间:2013-01-26 06:29:08

标签: c# ios xamarin.ios uiappearance

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

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

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

链接的答案说使用instancesRespondToSelector方法。但是我无法在MT API中的任何地方找到它。我只是瞎了,还是有不同的方式在MT中实现这个目标?

1 个答案:

答案 0 :(得分:4)

respondsToSelector:instancesRespondToSelector:之间存在很少差异,此处为good description,但后者是static方法。< / p>

答案来自您的链接,在真实类型上使用instancesRespondToSelector:,而不是Appearance代理。您可以使用MonoTouch中已有的RespondsToSelector获得相同的结果。

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

我认为如果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相同的答案(针对您的具体问题)。