2

UIButton内部でカスタムの[戻る]ボタンとして機能するサブクラスを作成しましたUIBarButtonItem

 - - - - - - - - - - - - - - - - - 
|         UIBarButtonItem         |

|     ------------------------    |
     /                       |
|    \ BackButton : UIButton |    |
      ------------------------
|  _  _  _  _  _  _  _  _  _  _  _|

コードをusingに切り替えていたときに、当然のことながら、から継承されUIAppearanceていることに気付きました。したがって、コードを変更すると、カスタムボタンだけでなく、アプリケーション全体のすべてが変更されます。BackButton.AppearanceUIButton.AppearanceUIButton

使用できることはわかっていますAppearanceWhenContainedInが、UIBarButtonItem外観コンテナではないため、戻るボタンを認識するためにそれらの間に別のビューを挿入する必要があります。これはやりたくないことです。

で使用可能なすべてのメソッドを持つUIAppearanceカスタムサブクラスのプロキシを提供するにはどうすればよいですか?そのコンストラクターが内部にあることに気づきました。UIButtonUIButton.UIButtonAppearance

4

2 に答える 2

1

より簡単な答えがあるかもしれませんが、MonoDevelop C# 逆アセンブラーからUIAppearance直接継承し、関連する部分UIButtonUIButton+UIButtonAppearanceバインド実装をコピーして貼り付け、あちこちで内部フィールドを修正することになりました。

内部BackButton:

static readonly IntPtr class_ptr = Class.GetHandle(typeof(BackButton));

public new static BackButtonAppearance Appearance
{
    get {
        return new BackButtonAppearance (Messaging.IntPtr_objc_msgSend (class_ptr, UIAppearance.SelectorAppearance));
    }
}

public new static BackButtonAppearance AppearanceWhenContainedIn (params Type[] containers)
{
    return new BackButtonAppearance (UIAppearance.GetAppearance (class_ptr, containers));
}

入れ子BackButtonAppearance:

public class BackButtonAppearance : UIAppearance {
    public BackButtonAppearance(IntPtr handle) : base(handle) { }

    // These are copied from UIButton disassembly:

    static readonly IntPtr selSetBackgroundImageForState_ = Selector.GetHandle ("setBackgroundImage:forState:");
    static readonly IntPtr selSetTitleShadowColorForState_ = Selector.GetHandle ("setTitleShadowColor:forState:");            
    static readonly IntPtr selSetTitleColorForState_ = Selector.GetHandle ("setTitleColor:forState:");

    // These are copied from UIButton+UIButtonAppearance disassembly,
    // with internal UIButton.selSet* fields replaced by fields declared above.

    [Export ("setBackgroundImage:forState:"), CompilerGenerated]
    public virtual void SetBackgroundImage (UIImage image, UIControlState forState)
    {
        UIApplication.EnsureUIThread ();
        if (this.IsDirectBinding) {
            Messaging.void_objc_msgSend_IntPtr_UInt32 (base.Handle, selSetBackgroundImageForState_, (image != null) ? image.Handle : IntPtr.Zero, (uint)forState);
        } else {
            Messaging.void_objc_msgSendSuper_IntPtr_UInt32 (base.SuperHandle, selSetBackgroundImageForState_, (image != null) ? image.Handle : IntPtr.Zero, (uint)forState);
        }
    }


    [Export ("setTitleColor:forState:"), CompilerGenerated]
    public virtual void SetTitleColor (UIColor color, UIControlState forState)
    {
        UIApplication.EnsureUIThread ();
        if (this.IsDirectBinding) {
            Messaging.void_objc_msgSend_IntPtr_UInt32 (base.Handle, selSetTitleColorForState_, (color != null) ? color.Handle : IntPtr.Zero, (uint)forState);
        } else {
            Messaging.void_objc_msgSendSuper_IntPtr_UInt32 (base.SuperHandle, selSetTitleColorForState_, (color != null) ? color.Handle : IntPtr.Zero, (uint)forState);
        }
    }

    [Export ("setTitleShadowColor:forState:"), CompilerGenerated]
    public virtual void SetTitleShadowColor (UIColor color, UIControlState forState)
    {
        UIApplication.EnsureUIThread ();
        if (this.IsDirectBinding) {
            Messaging.void_objc_msgSend_IntPtr_UInt32 (base.Handle, selSetTitleShadowColorForState_, (color != null) ? color.Handle : IntPtr.Zero, (uint)forState);
        } else {
            Messaging.void_objc_msgSendSuper_IntPtr_UInt32 (base.SuperHandle, selSetTitleShadowColorForState_, (color != null) ? color.Handle : IntPtr.Zero, (uint)forState);
        }
    }
}

これにより、カスタム ビューで UIAppearance スタイルの API をサポートできるようになります。

于 2012-10-17T18:55:00.177 に答える