一个非常好的问题,但更多的是关于 XIB 的工作原理以及我们可以做些什么。
问题是当您将对象添加到 XIB 并将其设置为自定义类时,您只需指示 UIKit 创建此对象的实例。您在 IB 中将其视为视图、按钮或任何控件的事实正是 IB 为您绘制它的方式。这样,创建前景的责任就完全落在了你的班级身上。
在 Objective-C 中,我们可以做一个很好的作弊,让 XIB 具有自定义视图,并且仍然通过设置添加视图的类名将它们添加到 IB。这是可能的,因为您可以从 Objective-C 中类的 -init 方法返回任何实例,而这在 C# 中是不可能的。
但是,您仍然可以通过执行以下操作来缓解生活:
- 让我们将XIB定义为包含自定义视图内容的 XIB;放置为您想要添加自定义视图的 XIB。
- 创建您的自定义视图类和一个 XIB 来放置它的内部
- 处理 AwakeFromNib 方法以实际加载您的 XIB
- 加载您的 XIB 后,只需将其内部作为子视图添加到您的实例中。
- 放置一个常规视图并将它的类设置为您自己的放置
- 享受!
但是,您必须接受您的 XIB 将包含一个根视图或其他东西,它将作为子视图添加到放入放置的类的实例中。
这样,你应该有类似的东西:
XIB 与您的自定义视图内容:
添加 XIB 的位置:
由于添加到放置的视图实例与 XIB 中的文件所有者相同,因此您可以在 XIB 和放置中设置出口和操作。只是不要忘记您的 XIB 中的根视图不是 UIKit 将创建以放置到 Placement 中的实例。
为方便起见,请在下面找到我的代码,它是基类以简化此类视图的创建:
using System;
using MonoTouch.ObjCRuntime;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace Member.iOS.Base.Views {
/// <summary>
/// XibView is a Xib-backed UIView subclass which enables easy customization and custom
/// behavior addition.
/// </summary>
public class XibView : UIView {
/// <summary>
/// Exception thrown when a loaded XIB doesn't contain any views inside it.
/// </summary>
class EmptyXibException : Exception {
}
/// <summary>
/// Initializes a new instance of the <see cref="Member.iOS.Base.Views.XibView"/> class.
/// </summary>
/// <param name='handle'>
/// Handle.
/// </param>
public XibView(IntPtr handle) : base(handle) {
}
/// <summary>
/// Upon loading from a containing XIB, takes care of replacing the current instance (which acts as a stab) with
/// a real view loaded from its XIB.
/// </summary>
public override void AwakeFromNib() {
base.AwakeFromNib();
NSArray views = NSBundle.MainBundle.LoadNib(GetType().Name, this, new NSDictionary());
if (views.Count == 0) {
throw new EmptyXibException();
}
UIView rootView = Runtime.GetNSObject(views.ValueAt(0)) as UIView;
rootView.Frame = new System.Drawing.RectangleF(0, 0, Frame.Width, Frame.Height);
AddSubview(rootView);
}
}
}