Where is the instance of MonoTouchRespondToSelector instance?

Different instances of the UIAppearance proxy do not respond to selectors (as they are the proxy of their respective types, not the actual instance) as discussed in this question and answer .

This makes it impossible to test new iOS 6 API Appearance features. for example this change in appearance will never be done because the code inside the if check always returns false, even on iOS 6, because the instance being checked is not a real instance but a proxy interface.

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

      

The reciprocal connection uses the method instancesRespondToSelector

. However, I cannot find it anywhere in the MT API. Am I just blind, or is there another way to achieve this in MT?

+3


source to share


1 answer


There are a few differences between respondsToSelector:

and instancesRespondToSelector:

, a good description here , except that the more recent version static

.

The answer from your link is using instancesRespondToSelector:

for the real type , not the proxy Appearance

. You can get the same result using the RespondsToSelector

one already available in MonoTouch.

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

      

IOW suppose if setShadowImage:

available you can get a proxy to it. This does not apply to functions that existed before UIAppearance

are available (the code may work, but the result will not meet your expectations).

is there any other way to achieve this in MT?



In many cases, you can enable / disable several features by checking one version like this:

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

      

instancesRespondToSelector:

Not part of the public API provided by MonoTouch right now (it needs to be bound in every type, at least using the generated bindings). However, it's not hard to implement if that's what you want. You can use this code:

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);

      

And you can turn it into a method if you need it in multiple places. Please be aware that it will return the same answer as RespondsToSelector

(for your specific question).

+4


source







All Articles