非常に良い質問ですが、それはXIBがどのように機能するか、そしてそれに対して何ができるかということです。
問題は、オブジェクトをXIBに追加し、それをカスタムクラスに設定する場合、UIKitにこのオブジェクトのインスタンスを作成するように指示するだけです。IBでビュー、ボタン、またはその他のコントロールとして表示されるという事実は、IBがそれを描画する方法です。このように、見通しを作成する責任は完全にクラスにあります。
Objective-Cでは、カスタムビューを備えたXIBを作成し、追加されたビューのクラス名を設定することで、それらをIBに追加するための優れたチートを行うことができます。これが可能なのは、Objective-Cのクラスの-initメソッドから任意のインスタンスを返すことができるためです。これはC#では不可能です。
ただし、次のようにすることで、生活を楽にすることができます。
- XIBを、カスタムビューのコンテンツを含むXIBとして定義しましょう。カスタムビューを追加するXIBとなる配置。
- カスタムビュークラスとXIBを作成して、その内部を配置します
- AwakeFromNibメソッドを処理して、実際にXIBをロードします
- XIBをロードした後、その内部をサブビューとしてインスタンスに追加するだけです。
- 通常のビューを配置し、クラスを独自のプレースメントに設定します
- 楽しみ!
ただし、XIBにルートビューなどが含まれることを受け入れる必要があります。これは、Placementに配置されたクラスのインスタンスにサブビューとして追加されます。
このように、次のようなものが必要です。
カスタムビューコンテンツを含む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);
}
}
}