各种 UIAppearance 代理实例不响应选择器(因为它们是相关类型的代理,而不是它的实际实例),如本 question and answer 中所讨论.
这使得无法测试 Appearance API 的新 iOS 6 功能。例如这种外观更改永远不会执行,因为 if 检查中的代码始终返回 false,即使在 iOS 6 上也是如此,因为它正在检查的实例不是真实实例,而是外观代理。
if ( UINavigationBar.Appearance.RespondsToSelector( new Selector("setShadowImage:")))
UINavigationBar.Appearance.ShadowImage = new UIImage();
链接的答案说使用 instancesRespondToSelector
方法。但是我无法在 MT API 中的任何地方找到它。我只是瞎了眼,还是有其他方法可以在 MT 中实现这一目标?
最佳答案
respondsToSelector:
和 instancesRespondToSelector:
之间很少有区别,这里是good description , 除了后者是一个 static
方法。
您的链接中的答案使用 instancesRespondToSelector:
real 类型,而不是其 Appearance
代理。您可以使用 MonoTouch 中已提供的 RespondsToSelector
获得相同的结果。
if (new UINavigationBar ().RespondsToSelector( new Selector("setShadowImage:")))
UINavigationBar.Appearance.ShadowImage = new UIImage();
IOW 它假设如果 setShadowImage:
可用,那么您可以访问它的代理。对于 UIAppearance
可用之前存在的功能而言,情况并非如此(代码可能有效,但结果不符合您的预期)。
is there a different way to achieve this in MT?
在许多情况下,您可以通过像这样进行单个版本检查来启用/禁用多个功能:
if (UIDevice.CurrentDevice.CheckSystemVersion (6,0)) {
// enable iOS6 new features
} else {
// fallback to iOS 5.x supported features
}
现在 instancesRespondToSelector:
不是 MonoTouch 提供的公共(public) API 的一部分(它需要在每种类型中绑定(bind),至少在使用生成的绑定(bind)完成时)。但是,如果您愿意,实现起来并不难。您可以使用此代码:
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
相同的答案(针对您的特定问题)。
关于c# - MonoTouch instancesRespondToSelector 实现在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14534509/