如何使用 Interface Builder 中的自定义 UITableViewCell?

Posted

技术标签:

【中文标题】如何使用 Interface Builder 中的自定义 UITableViewCell?【英文标题】:How to use custom UITableViewCell from Interface Builder? 【发布时间】:2011-03-19 22:33:39 【问题描述】:

我希望能够在 IB 中设计自己的 UITableViewCell。 但是在尝试访问我在 IB 中定义的标签时,我不断收到 null ref 异常。

这就是我正在做的事情:

在界面生成器中:

我删除了“视图”并添加了一个 UITableViewCell。 将 UITableViewCell 的类更改为“TestCellView”。 向单元格添加了 UILabel。 为TestCellView添加了一个出口“oLblText”并将UILabel连接到它。 将类的标识符更改为“TestCellView”。

实现TestCellView.xib.cs

public partial class TestCellView : UITableViewCell

    public TestCellView(string sKey) : base(UITableViewCellStyle.Default, sKey)
    
    

    public TestCellView(IntPtr oHandle) : base(oHandle)
    
    

    public string TestText
    
        get
        
            return this.oLblText.Text;
        
        set
        
                        // HERE I get the null ref exception!
            this.oLblText.Text = value;
        
    

** TestCellView.designer.cs**

[MonoTouch.Foundation.Register("TestCellView")]
public partial class TestCellView 

    private MonoTouch.UIKit.UILabel __mt_oLblText;

    #pragma warning disable 0169
    [MonoTouch.Foundation.Connect("oLblText")]
    private MonoTouch.UIKit.UILabel oLblText 
        get 
            this.__mt_oLblText = ((MonoTouch.UIKit.UILabel)(this.GetNativeField("oLblText")));
            return this.__mt_oLblText;
        
        set 
            this.__mt_oLblText = value;
            this.SetNativeField("oLblText", value);
        
    

在我的表格来源中:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)

    TestCellView oCell = (TestCellView)tableView.DequeueReusableCell("myCell");
    if(oCell == null)
    
        // I suppose this is wrong but how to do it correctly?
                // this == my UITableViewSource.
                NSBundle.MainBundle.LoadNib("TestCellView", this, null);
        oCell = new TestCellView("myCell");
    
    oCell.TestText = "Cell " + indexPath.Row;
    return oCell;

请注意,我不想要一个涉及每个单元格的 UIViewController 的解决方案。我在网上看到了几个这样做的例子。我只是认为这完全是矫枉过正。

我做错了什么?

【问题讨论】:

【参考方案1】:

首先,这是一个设计问题。如果您的表格视图总是加载特定数量的包含静态内容的单元格,例如在“设置”视图中,请为您想要的每一行创建一个自定义单元格,并将每个单元格与一个插座连接。

如果不是这样,那么您有两种选择:

    以编程方式创建一个继承 UITableViewCell 和您想要在其中的每个视图的类,忘记 Interface Builder。 使用控制器添加一个新的 iPhone 视图,替换其中的视图并像以前一样处理它。除了您必须将您的单元格连接到文件所有者中的插座这一事实之外。因此,当您实例化该控制器时,您的所有单元格子视图都会正常。

这不是矫枉过正,或者至少,Apple 推荐它:click and go to the "Loading Custom Table-View Cells From Nib Files" paragraph

PS:刚刚遇到过类似的情况,我就是这样做的。对于此示例,在 MonoTouch 中,您不必LoadNib 任何内容。只需在表源中的 GetCell 覆盖内执行此操作:

using (CellController controller = new CellController())


     cell = (CustomCell)controller.View;


甚至可以在 CellController 对象内声明一个额外的出口以避免从 UIView 进行转换。

【讨论】:

我现在就是这样。我只是不喜欢有控制器。原因是:使用默认单元格样式时,我也没有控制器。因此,Apple 决定不需要控制器。创建自定义单元格时,他们希望我们每个单元格有一个控制器。 是的,当您使用默认单元格样式时,不需要控制器,因为单元格是以编程方式创建的。但是您想使用从 NIB 文件加载的单元格,通常是用户界面对象。仅将自定义单元格放入 NIB 文件是不够的。它必须以某种方式与其文件所有者连接,在这种情况下,它必须是 UIViewController。【参考方案2】:

在加载 Nib 之前,您不能引用任何插座。您可以覆盖一种方法,它会告诉您“您的 NIB 已加载,您现在可以访问这些字段”。在此之前,引用这些对象将始终返回 null。

【讨论】:

【参考方案3】:

检查此link。这是一篇关于创建自定义 TableViewCell 的非常有趣的文章。我认为这个错误是由于 Monotouch 提供的 xib 的异步加载造成的。

您必须像这样提供自己的构造函数:

public TestCellView(string sKey) //: base(UITableViewCellStyle.Default, sKey)

    MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("YOUR NIBNAME", this, null);

希望这会有所帮助!

【讨论】:

根据您在此处提供的链接,您在上面输入的代码示例不正确。链接中的示例在 controller 实现内部而不是在单元实现内部调用 LoadNib。

以上是关于如何使用 Interface Builder 中的自定义 UITableViewCell?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Interface Builder 中的 UIViewController 中自动调整 UIView Outlet 的大小

如何让 UISearchController 与 UISearchBar Interface Builder 控件一起使用?

在 Cocoa/Interface Builder 中,单击按钮后如何清除文本字段中的文本

如何将 UITableViewCell 的内容视图转换为 Interface Builder 中的普通 UIView?

Interface Builder 文件中的未知类 FirstViewController

如何从 XCode 4 Interface Builder 更改 NSScrollView 字体?