我创建的子类UIButton
充当内自定义后退按钮UIBarButtonItem
:
- - - - - - - - - - - - - - - - -
| UIBarButtonItem |
| ------------------------ |
/ |
| \ BackButton : UIButton | |
------------------------
| _ _ _ _ _ _ _ _ _ _ _|
当我转换我的代码使用UIAppearance
,我注意到BackButton.Appearance
是,unsuprisingly,从继承UIButton.Appearance
,因此改变它会改变所有UIButton
小号整个应用程序,而不是只是我的自定义按钮。
我知道我可以使用AppearanceWhenContainedIn
但是,因为UIBarButtonItem
不是外观的容器,我不得不插入它们之间的另一种观点认识到后退按钮,这是我不想做的事。
如何提供一个UIAppearance
为我的自定义代理UIButton
子类,在所有可用的方法UIButton.UIButtonAppearance
? 我注意到,它的构造是内部的。
虽然有可能是一个简单的答案,我结束了继承UIAppearance
直接复制粘贴相关一块UIButton
和UIButton+UIButtonAppearance
从MonoDevelop的C#反汇编结合实施,在这里和那里固定内部字段。
内部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。
添加答案的完整性。
使用BackButton.GetAppearance<BackButton>()
代替BackButton.Appearance
。