我创建了 UIButton
的子类,它充当 UIBarButtonItem
内的自定义后退按钮:
- - - - - - - - - - - - - - - - -
| UIBarButtonItem |
| ------------------------ |
/ |
| \ BackButton : UIButton | |
------------------------
| _ _ _ _ _ _ _ _ _ _ _|
当我将代码切换为使用 UIAppearance
时,我注意到 BackButton.Appearance
毫不奇怪地继承自 UIButton.Appearance
,因此,更改它会更改整个应用程序中的所有 UIButton
,而不仅仅是我的自定义按钮。
我知道我可以使用 AppearanceWhenContainedIn
但是,因为 UIBarButtonItem
不是外观容器,我必须在它们之间插入另一个 View 来识别后退按钮,我不想做。
如何为具有 UIButton.UIButtonAppearance
中所有可用方法的自定义 UIButton
子类提供 UIAppearance
代理?我注意到它的构造函数是内部的。
最佳答案
虽然可能有一个更简单的答案,但我最终直接继承了 UIAppearance
并复制粘贴了 UIButton
和 UIButton+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/