c# - 如何在 MonoTouch 中为继承 View 创建 UIAppearance 代理?

标签 c# ios5 xamarin.ios uibutton uiappearance

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

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

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

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

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

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

最佳答案

虽然可能有一个更简单的答案,但我最终直接继承了 UIAppearance 并复制粘贴了 UIButtonUIButton+UIButtonAppearance 的相关部分> 绑定(bind) MonoDevelop C# 反汇编器的实现并修复内部字段。

返回按钮内部:

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

这使我能够将自定义 View 支持 UIAppearance 风格的 API。

关于c# - 如何在 MonoTouch 中为继承 View 创建 UIAppearance 代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12939321/

相关文章:

c# - 单击 WPF 超链接时打开 WPF 窗体

iPad FormSheet/PageSheet 模态视图,旋转时会填满整个屏幕。T

iphone - 警告 : Supported orientations are not matched pairs (Info. plist)

C#线程和同步

c# - 对于每个循环迭代

objective-c - present Modal ViewController 给出黑屏

ios - 在 iOS 应用中使用 AdMob

ios5 - 在显示标签栏 Controller 之前启动登录 View

c# - xamarin 意图扩展与 netstandard 导致 MT2001 错误

c# - 如何创建一个将属于解决方案资源管理器中某个类的类?