在 MonoTouch iPhone 应用程序中,如何在单个 NIB 文件中拥有多个 UITableViewCell?

发布于 2024-10-28 19:56:43 字数 821 浏览 3 评论 0 原文

在 MonoTouch 中,有很多这样的例子,人们加载 NIB 文件:

var customController = new MyCustomController();
NSBundle.MainBundle.LoadNib("MyCustomController", customController, null);

根据我在博客文章中看到的许多代码示例,人们倾向于对他们在 Interface Builder 中设计的自定义 UITableViewCell 执行此操作。

这一切都很好 - 但也许 NIB 文件包含多个自定义 UITableViewCell。我发现一篇博客文章显示正在使用的单个 NIB 文件包含多个自定义表格单元格(在 Objective-C 中): http://pegolon.wordpress.com/2008/11/ 15/using-uitableviewcell-with-interfacebuilder/

这就是我想要的!

在那个 Objective-C 示例中,很明显 NSBundle.MainBundle.LoadNib 实际上返回一些东西(一个 NSArray),然后迭代返回的对象:NSArray 中的每个对象都是一个表格单元格“模板”。

当我尝试在 MonoTouch/C# 中执行此操作时,我很难迭代返回的 NSArray。它不允许我使用数组索引器访问其内容,也不允许我循环遍历它。

我该怎么做呢?

In MonoTouch, there are many examples out there where people load NIB files like this:

var customController = new MyCustomController();
NSBundle.MainBundle.LoadNib("MyCustomController", customController, null);

Based on many code samples I have seen on blog posts, people tend to do this for custom UITableViewCells which they have designed in Interface Builder.

That is all well and good - but perhaps the NIB file contains more than one custom UITableViewCell. I have found a blog post that shows a single NIB file being used that contains multiple custom table cells (in Objective-C):
http://pegolon.wordpress.com/2008/11/15/using-uitableviewcell-with-interfacebuilder/

That is doing what I want!

In that Objective-C example, it becomes clear that NSBundle.MainBundle.LoadNib actually returns something (an NSArray) and then the returned object is iterated over: each object in the NSArray is a table cell "template".

When I try to do this in MonoTouch/C#, I am struggling to iterate over the returned NSArray. It doesn't let me access its contents with array indexers, and it won't let me loop over it.

How can I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不即不离 2024-11-04 19:56:43

好吧,我已经成功让它工作了。重要的是如何从 NSArray 获取对象:

NSArray nsArr = NSBundle.MainBundle.LoadNib("MyCustomController", customController, null);
UITableViewCell = (UITableViewCell)Runtime.GetNSObject(nsArr.ValueAt(0)); // gets the first item

我还创建了一个示例项目和关于如何从 nib 文件使用自定义表格单元格的文章

: tavlikos.com/2011/04/03/uitableviewcell-nib/" rel="nofollow" title="MonoTouch 中的自定义表格单元">MonoTouch 中的自定义表格单元

Ok, I have managed to get it working. The important thing is how to get objects from an NSArray:

NSArray nsArr = NSBundle.MainBundle.LoadNib("MyCustomController", customController, null);
UITableViewCell = (UITableViewCell)Runtime.GetNSObject(nsArr.ValueAt(0)); // gets the first item

I have also created a sample project and article about how to use custom table cells from nib files:

Custom Table Cells in MonoTouch

我们的影子 2024-11-04 19:56:43

正如对 Eduardo Scoz 的回答的评论中提到的,如果不进行一些调整,XCode 4 就不可能实现所描述的工作流程。 XCode 4 中的 Interface Builder 无法为您进行子类化,您必须自己进行子类化。
以下是在 MonoTouch 中创建没有控制器的子类视图的完整工作流程。这对于表视图单元格和其他可重用视图很有用。

  1. 首先在 MonoTouch 中创建一个新的空类。将班级命名为您喜欢的任何名称。
  2. 打开新创建的类文件,并继承你想要的类。 (UIView、UITableViewCell 等)
  3. 将属性[Register("yourClassName")] 添加到
  4. 通过创建具有自动 getter 和 setter 的属性(不必公开)来添加您想要的插座。将属性[Outlet] 添加到属性中。
  5. 如果需要,可以向类添加操作。像这样声明它们:[Action("MethodName")]
    公共无效方法名称(NSObject发送者){}
    。我相信也可以将该方法声明为私有,但我还没有尝试过。
  6. 创建具有以下签名的构造函数方法:public YourClassName(IntPtr ptr) : base(ptr) {}。如果您忘记了此步骤,当您尝试从代码加载 XIB 文件时,您将收到异常,告诉您找不到此构造函数。
  7. 确保保存文件。
  8. 现在将新的 iPhone 或 iPad 视图添加到您的项目中。 (只是一个视图,不是视图控制器
  9. 通过双击 MonoDevelop 中的视图来打开 Interface Builder 中的视图。
  10. 在 Interface Builder 中,选择已有的视图并打开 Identity Inspector。
  11. 将类更改为您之前创建的类的名称。 Interface Builder 应该会自动为您补全名称。
  12. 现在,使用标签、按钮等设置视图。
  13. 现在,打开 Interface Builder 中的助手视图(如果尚未打开)。
  14. 看看那个!您在 C# 类文件中所做的所有出口和操作都位于助手显示的 Objective C 类中。现在您可以将视图上的控件连接到现有的插座和操作。
  15. 完成后,请确保保存正在编辑的 XIB 文件并返回到 MonoDevelop。

要实例化视图,请按照 Dimitris 所写:

NSArray nsArr = NSBundle.MainBundle.LoadNib("YourViewName", theController, null);
YourClassName instantiatedView = (YourClassName)Runtime.GetNSObject(nsArr.ValueAt(0));

theController 是将被设置为视图的文件所有者的视图控制器。据我所知,您必须将有效的视图控制器传递给该方法。如果您在视图控制器中实例化视图,则可以将 this 传递给该方法。
现在您可以使用在视图中定义的任何属性或方法来更改视图的外观。因此,如果您已将 UILabel 连接到插座属性 Name(并且将其声明为公共),则可以使用 instantiatedView.Name.Text = "John Doe";
但是,您不应该在所有情况下都使用此技术来摆脱视图控制器。视图控制器的作用是分离职责。因此,如果您需要一些更复杂的视图逻辑,您应该重新考虑这是否是正确的方法。

As mentioned in a comment to Eduardo Scoz's answer, the workflow described is not possible with XCode 4 without some adjustment. Interface Builder in XCode 4 is not able to subclass for you, you have to do that yourself.
Here is the complete workflow in MonoTouch to create a subclassed view without a controller. This is useful for table view cells and other reusable views.

  1. Start by creating a new empty class in MonoTouch. Name the class anything you like.
  2. Open the newly created class file, and inherit from the class you want to. (UIView, UITableViewCell etc.)
  3. Add the attribute [Register("yourClassName")] to the class.
  4. Add the outlets you want by creating a property (It doesn't have to public) with automatic getter and setter. Add the attribute [Outlet] to the property.
  5. Add actions to the class if you want. Declare them like this: [Action("MethodName")]
    public void MethodName(NSObject sender) {}
    . I believe it's possible to declare the method private as well, but I haven't tried it.
  6. Create a constructor method with the following signature: public YourClassName(IntPtr ptr) : base(ptr) {}. If you forget this step, you'll get an exception when you try to load the XIB file from code, telling you it couldn't find this constructor.
  7. Make sure you save the file.
  8. Now add a new iPhone or iPad view to your project. (Just a view, not a view controller)
  9. Open the view in Interface Builder by double clicking the view in MonoDevelop.
  10. In Interface Builder, select the view that's already there and open the Identity Inspector.
  11. Change the class to the name of the class you created earlier. Interface Builder should autocomplete the name for you.
  12. Now, set up your view with labels, buttons, etc.
  13. Now, turn on the Assistant View in Interface Builder, if it's not already turned on.
  14. Just look at that! All the outlets and actions you made in the C# class file is in the Objective C class the Assistant is showing. Now you can connect the controls on your view to the existing outlets and actions.
  15. When you're done, make sure you save the XIB file you've been editing and go back to MonoDevelop.

To instantiate the view, you do as Dimitris wrote:

NSArray nsArr = NSBundle.MainBundle.LoadNib("YourViewName", theController, null);
YourClassName instantiatedView = (YourClassName)Runtime.GetNSObject(nsArr.ValueAt(0));

theController is the View Controller that will be set as the view's File Owner. As far as I know, you have to pass a valid View Controller to the method. If you're instantiating the view in a View Controller, you can pass this to the method.
And now you can use whatever properties or methods you've defined in your view to change the appearance of the view. So if you've connected a UILabel to the outlet property Name (And it's declared as public), you can use instantiatedView.Name.Text = "John Doe";
However, you should not use this technique to get rid of the view controller in all situations. The view controller is there to seperate responsibilities. So if you need some more complex logic for the view, you should reconsider if this is the right way to go.

但可醉心 2024-11-04 19:56:43

我承认我在这方面失败了,并采取了解决方法。我让单元格构​​造函数在静态变量中粘贴对其自身的引用,然后在 LoadNib 之后访问该引用。

我认为这样做是安全的,因为我只从主线程实例化单元格,因此我不会有任何竞争条件导致任何问题。

public partial class OrderPrimary : UITableViewCell
{
    static OrderPrimary lastCell;

    public OrderPrimary(IntPtr handle) : base(handle)
    {
         lastCell=this;
    }

    static public OrderPrimary NewCell()
    {
         NSObject obj=new NSObject();
         NSBundle.MainBundle.LoadNib("OrderPrimary",obj,null);

         return lastCell;
    }
}

不大也不聪明,但对我有用。我不知道如何以其他方式获得它......欢迎评论!

请注意,在此示例中,我只有 XIB 中的一个视图。

I confess I failed on this and took a workaround. I made my cell constructor stick a reference to itself in a static variable, and then accessed that after LoadNib.

I figured I was safe doing this as I only ever instantiated cells from the main thread, and hence I would not have any race conditions causing any problems.

public partial class OrderPrimary : UITableViewCell
{
    static OrderPrimary lastCell;

    public OrderPrimary(IntPtr handle) : base(handle)
    {
         lastCell=this;
    }

    static public OrderPrimary NewCell()
    {
         NSObject obj=new NSObject();
         NSBundle.MainBundle.LoadNib("OrderPrimary",obj,null);

         return lastCell;
    }
}

Not big or clever but works for me. I couldn't work out how to get at it any other way.. comments welcomed!

Note in this example I have just the one view in a XIB.

阪姬 2024-11-04 19:56:43

我还没有在单元格视图中尝试过此操作,但我认为使其正常工作的最佳方法是在定义单元格时使用界面生成器的继承。

基本上,您必须在 IB 中定义 UITableCellView 的子类(右键单击该类,然后“添加子类”)。使用该类来创建单元格。当 MonoTouch 刷新项目中的 .cs.design 文件时,它将为这些类型创建部分类,您必须完成实现(确保您的实现继承自 UITableViewCell。之后,这应该只是一个问题使用 new CustomTableViewCell() 创建新单元格

我之前写过有关 UIViews 的内容,但单元格的过程应该是相同的:http://escoz.com/monotouch-tip-inherit-uiviews-all-the-time/希望这有帮助。

I haven't tried this for cell views, but I think the best way to get this to work properly is to use inheritance from interface builder when defining your cell.

Basically, you have to define a subclass of UITableCellView in IB (right click the class, and "add subclass"). Use that class to create the cell. When MonoTouch refreshes the .cs.design file in your project, it'll create partial classes for those types, which you'll have to finish the implementation (make sure your implementation inherits from UITableViewCell. After that, it should be just a matter of creating new cells with new CustomTableViewCell().

I wrote a while back about this going thru this with UIViews, but the process should be the same for cells: http://escoz.com/monotouch-tip-inherit-uiviews-all-the-time/. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文