各种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中实现这个目标?
答案 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
相同的答案(针对您的具体问题)。