8

使用 MonoTouch,我正在尝试制作自定义视图,因此我可以在屏幕中多次重复使用此视图。(这是一堆标签和按钮)在阅读了这篇文章的答案后: 如何在 monotouch 中将自定义视图添加到 XIB 文件定义的视图中, 我必须接近,但这似乎只允许我添加自定义视图,在 myCustomView.CS 中定义,但我正在寻找的是一种使用单独的 .XIB 在界面构建器中设计我的自定义视图并且仅使用相应的 cs 文件来添加逻辑的方法。如果我尝试创建一个同名的 XIB,则内容将不可见。

遵循的步骤:

  • 在 MyCustomView.CS 我放了[Register("MyCustomView")].

  • 我实现了构造函数public MyView(IntPtr handle) : base(handle) {}

  • 在 Interface Builder 中打开 ViewController.XIB,添加一个 UIView 并将其 Class 设置为 MyCustomView。

当我运行这段代码时,我看到了新添加的 UIView,但没有看到视图内部的元素,即 MyCustomView.XIB 的内容

如果我在 MyCustomView.CS 的代码中添加一些内容,this.Backgroundcolor = UIColor.Blue;则会显示这样的内容,但不会显示任何添加到 .XIB 的元素。如何告诉 Monotouch 显示 MyCustomView.XIB 中定义的所有内容?

在 Objective-C 示例中,我看到诸如“initWithNib”之类的东西不幸的是,Monotouch api 中没有记录“LoadNib”部分,但这听起来像是我应该做的事情,但是如何以及在哪里?

4

3 回答 3

8

根据我在 obj-c 代码方面的经验,我将尝试以下代码:

var views = NSBundle.MainBundle.LoadNib(nibName, this, null); // (1)
MyCustomView myView = Runtime.GetNSObject(views.ValueAt(0)) as MyCustomView; // (2)

(1)允许你加载xib文件

(2) 允许您将 IntPtr 转换为适当类型的 NSObject(子)类型。

拥有myView后,您可以将其添加为传统视图。检查您是否正确设置了视图的输出。

PS如果您提供一些其他详细信息,我们可以帮助您。此外,请检查代码,因为我是手写的。

于 2012-06-27T20:48:12.203 回答
6

一个非常好的问题,但更多的是关于 XIB 的工作原理以及我们可以做些什么。

问题是当您将对象添加到 XIB 并将其设置为自定义类时,您只需指示 UIKit 创建此对象的实例。您在 IB 中将其视为视图、按钮或任何控件的事实正是 IB 为您绘制它的方式。这样,创建前景的责任就完全落在了你的班级身上。

在 Objective-C 中,我们可以做一个很好的作弊,让 XIB 具有自定义视图,并且仍然通过设置添加视图的类名将它们添加到 IB。这是可能的,因为您可以从 Objective-C 中类的 -init 方法返回任何实例,而这在 C# 中是不可能的。

但是,您仍然可以通过执行以下操作来缓解生活:

  1. 让我们将XIB定义为包含自定义视图内容的 XIB;放置为您想要添加自定义视图的 XIB。
  2. 创建您的自定义视图类和一个 XIB 来放置它的内部
  3. 处理 AwakeFromNib 方法以实际加载您的 XIB
  4. 加载您的 XIB 后,只需将其内部作为子视图添加到您的实例中。
  5. 放置一个常规视图并将它的类设置为您自己的放置
  6. 享受!

但是,您必须接受您的 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);
        }

    }
}
于 2012-11-10T19:51:55.040 回答
0

您可以使用容器视图代替 nib 文件来简化操作。你可以尝试这样的事情

于 2019-03-02T09:00:25.550 回答