使用xib创建自定义视图

时间:2012-06-25 11:37:31

标签: view xamarin.ios xib nib

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

以下步骤:

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

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

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

当我运行此代码时,我看到新添加的UIView,但不是视图中的元素,即MyCustomView.XIB的内容

如果我在MyCustomView.CS的代码中添加了一些东西,比如显示this.Backgroundcolor = UIColor.Blue;,那么添加到.XIB的任何元素都不会。如何告诉Monotouch显示MyCustomView.XIB中定义的所有内容?

在Objective-C示例中,我看到类似“initWithNib”的内容 不幸的是,Monoouch api中没有记录“LoadNib”部分,但这听起来像我应该做的,但是如何以及在哪里?

3 个答案:

答案 0 :(得分:6)

根据我在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后,您可以将其添加为传统视图。检查您是否为视图正确设置了outelt。

P.S。如果您提供其他一些细节我们可以帮助您。此外,检查代码,因为我是手写的。

答案 1 :(得分:5)

一个非常好的问题,但它更多的是关于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. 享受!
  7. 但是,您必须接受您的XIB将包含根视图或其他内容,将作为子视图添加到您的类的实例中 Placement

    这样,你应该有:

    带有自定义视图内容的XIB:

    XIB with your custom view contents

    添加XIB的位置:

    Placement where you add your 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);
            }
    
        }
    }
    

答案 2 :(得分:0)

您可以使用容器视图代替nib文件,以使其变得简单。您可以尝试类似this.