3

この質問と回答で説明されているように、さまざまな UIAppearance プロキシ インスタンスはセレクターに応答しません (セレクターは関連するタイプのプロキシーであり、実際のインスタンスではないため) 。

これにより、Appearance API の新しい iOS 6 機能をテストすることができなくなります。たとえば、この外観の変更は、iOS 6 でも if チェック内のコードが常に false を返すため実行されません。これは、チェックしているインスタンスが実際のインスタンスではなく、外観プロキシであるためです。

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

setShadowImage:IOWが利用可能であれば、そのプロキシにアクセスできると想定しています。これは、利用可能になる前に存在していた機能には当てはまりませ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 に答える