在 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?
发布评论
评论(4)
好吧,我已经成功让它工作了。重要的是如何从 NSArray 获取对象:
我还创建了一个示例项目和关于如何从 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
:I have also created a sample project and article about how to use custom table cells from nib files:
Custom Table Cells in MonoTouch
正如对 Eduardo Scoz 的回答的评论中提到的,如果不进行一些调整,XCode 4 就不可能实现所描述的工作流程。 XCode 4 中的 Interface Builder 无法为您进行子类化,您必须自己进行子类化。
以下是在 MonoTouch 中创建没有控制器的子类视图的完整工作流程。这对于表视图单元格和其他可重用视图很有用。
[Register("yourClassName")]
添加到类。[Outlet]
添加到属性中。[Action("MethodName")]
。我相信也可以将该方法声明为私有,但我还没有尝试过。公共无效方法名称(NSObject发送者){}
public YourClassName(IntPtr ptr) : base(ptr) {}
。如果您忘记了此步骤,当您尝试从代码加载 XIB 文件时,您将收到异常,告诉您找不到此构造函数。要实例化视图,请按照 Dimitris 所写:
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.
[Register("yourClassName")]
to the class.[Outlet]
to the property.[Action("MethodName")]
. I believe it's possible to declare the method private as well, but I haven't tried it.public void MethodName(NSObject sender) {}
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.To instantiate the view, you do as Dimitris wrote:
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 passthis
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.
我承认我在这方面失败了,并采取了解决方法。我让单元格构造函数在静态变量中粘贴对其自身的引用,然后在 LoadNib 之后访问该引用。
我认为这样做是安全的,因为我只从主线程实例化单元格,因此我不会有任何竞争条件导致任何问题。
不大也不聪明,但对我有用。我不知道如何以其他方式获得它......欢迎评论!
请注意,在此示例中,我只有 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.
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.
我还没有在单元格视图中尝试过此操作,但我认为使其正常工作的最佳方法是在定义单元格时使用界面生成器的继承。
基本上,您必须在 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.