如何在MonoTouch中为继承的视图创建UIAppearance代理? [英] How to create a UIAppearance proxy for an inherited view in MonoTouch?

查看:110
本文介绍了如何在MonoTouch中为继承的视图创建UIAppearance代理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个 UIButton 的子类,它充当 UIBarButtonItem 中的自定义后退按钮:

I created a subclass of UIButton which acts as a custom Back button inside UIBarButtonItem:

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

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

当我将代码切换为使用 UIAppearance ,我注意到 BackButton.Appearance 是毫无疑问的,继承自 UIButton.Appearance ,因此更改它将会改变整个应用程序中的所有 UIButton ,而不仅仅是我的自定义按钮。

As I was switching my code to using UIAppearance, I noticed that BackButton.Appearance is, unsuprisingly, inherited from UIButton.Appearance, and therefore changing it will change all UIButtons throughout the application and not just my custom buttons.

我知道我可以使用 AppearanceWhenContainedIn 但是,因为 UIBarButtonItem 不是外观容器,我必须在它们之间插入另一个视图以识别后退按钮,我我不想这样做。

I know I can use AppearanceWhenContainedIn but, because UIBarButtonItem is not an appearance container, I'd have to insert another view between them to recognize back buttons, which I don't want to do.

如何为我的自定义 UIAppearance 代理> UIButton 具有 UIButton.UIButtonAppearance 中所有可用方法的子类?我注意到它的构造函数是内部的。

How do I provide a UIAppearance proxy for my custom UIButton subclass that has all the methods available in UIButton.UIButtonAppearance? I noticed that its constructor is internal.

推荐答案

虽然可能有一个更简单的答案,但我最终继承了 UIAppearance 直接复制粘贴相关的 UIButton UIButton + UIButtonAppearance 绑定从MonoDevelop C#反汇编程序实现并在此处修复内部字段。

Although there may be a simpler answer, I ended up inheriting from UIAppearance directly and copy-pasting relevant piece of UIButton and UIButton+UIButtonAppearance binding implementation from MonoDevelop C# disassembler and fixing internal fields here and there.

内部 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。

This allows me to bring my custom view to support UIAppearance-style API.

这篇关于如何在MonoTouch中为继承的视图创建UIAppearance代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆