Xamarin中的UINib.DequeueReusableCell始终返回null

3
我创建了一个简单的视图控制器,其中包含一个表格视图。我随后创建了一个.xib文件来设计将放入表格中的UITableViewCells。
无论我尝试什么,GetCell都无法找到UITableViewCell Nib。我已经尝试了所有名称/ ID和类型转换的变化。作为Xamarin和C#的新手,我可能漏掉了一些简单的东西。
视图控制器:
public partial class ScheduleViewController : BaseViewController<ScheduleViewModel>
{
    [Export("initWithBundle:owner:extras:")]
    public ScheduleViewController(NSBundle bundle, UIViewController owner, string extras) : base("ScheduleViewController", bundle, owner, extras)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        Dictionary<string, List<string>> itemData = new Dictionary<string, List<string>>()
        {
            {"phones", new List<string>() {
                "Android",
                "iOS",
                "Windows Phone",
                "Other",
                "The Thing"
            }},
            {"computers", new List<string>() {
                "osx",
                "windows",
                "linux"
            }}
        };

        UITableView table = new UITableView(View.Bounds);
        table.Source = new ScheduleTableViewSource(itemData);
        table.SeparatorStyle = UITableViewCellSeparatorStyle.None;
        Add(table);
    }

UITableVIewCell类:

public partial class WorkCell : UITableViewCell
{
    public static readonly NSString Key = new NSString("WorkCell");
    public static readonly UINib Nib;

    static WorkCell()
    {
        Nib = UINib.FromName("WorkCell", NSBundle.MainBundle);
    }

    protected WorkCell(IntPtr handle) : base(handle)
    {
        // Note: this .ctor should not contain any initialization logic.
    }
}

WorkCell .xib文件

图片描述

图片描述

TableViewDataSource:


注:本文涉及IT技术相关内容。
    public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
    {
        // always null
        UINib nib = UINib.FromName("WorkCellContainer", NSBundle.MainBundle);
tableView.RegisterNibForCellReuse(nib, "workItemCell");
        var cell = (WorkCell)tableView.DequeueReusableCell ("workItemCell");

        return cell;
}

如果UITableView从故事板中没有出列单元格,则尝试检查是否使用原型单元格而不是静态单元格。UITableView将不会出列静态单元格。 - Lucas Zhang
@LucasZhang-MSFT 这不是来自“故事板”,而是来自.xib文件。我通过代码实例化表格,单元格的布局是在它自己的.xib文件中完成的。 - Phil Andrews
2个回答

2
在 GetCell 方法中加载 nib 并非必要。如果要使用来自 xib 的自定义单元格,只需要执行以下操作:
- 创建带有上下文菜单的 xib(<Add/New File> 选择 iOS,选择 Table View Cell) - 在您的 ViewController 子类中注册该 nib,以便重用单元格 - 设置重用标识符(为简单起见,只需使用与单元格名称相同的名称) - 当出列单元格时,请使用重用标识符 注册 NIB 在 UITableViewController 子类中的 ViewDidLoad 中(例如在设置 DataSource 之前),添加以下内容:
table.RegisterNibForCellReuse(WorkCell.Nib, WorkCell.Key);

设置单元格重用标识符

reuse identifier

出列单元格

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell(WorkCell.Key, indexPath) as WorkCell;

    //set the data in work cell here


    return cell;
}

在模拟器中测试

在模拟器中测试


就我所看到的,这与我的答案相同...所以是的,这应该可以工作,但他说它不行... - Ivan Ičin
1
有一些小差别:xib没有名称,重用标识符与单元格使用相同的名称,充分利用WorkCell.Nib和WorkCell.Key在调用RegisterNibForCellReuse时,将其放在ViewDidLoad中完成 - 还描述了只需遵循四个步骤即可运行自定义单元格 - 希望这能让生活更轻松。 - Stephan Schlecht
我仍然只看到“好”的回复,就像他们所说的,你有宪法权利发布相似的答案 ;)。 - Ivan Ičin
啊,我明白了。我只是试图友好地表达它。所以事实是:1)你的解决方案不起作用,因为出队将失败。2)每当显示表格单元格时,都会调用GetCell。当用户滚动时,这可能非常频繁。在代码审查期间,除了出队和填充单元格之外,不应该在那里做其他事情,这被认为是一种不良实践。在公司中,这段代码不会通过审查。3)特别是每次需要单元格时调用RegisterNibForCellReuse没有意义(更大的列表,用户滚动,数百次)。你的结果可能会有所不同。 - Stephan Schlecht
这个可行。需要注意的一个重要事项是,单元格“名称”属性需要留空。如果不留空,你会得到一个“类不符合键值编码”的错误。对我来说,这似乎是 VS Mac 自动将设计文件与 xib 连接的 bug。 - Phil Andrews
显示剩余4条评论

0

这应该可以工作,虽然你只展示了 xib 文件的一部分,所以可能我理解错了什么:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
        UINib nib = UINib.FromName("WorkCell", NSBundle.MainBundle);
        tableView.RegisterNibForCellReuse(nib, "workCellContainer");
        var cell = (WorkCell)tableView.DequeueReusableCell ("workCellContainer");

        return cell;
}

虽然这样做应该可以工作,但没有必要在GetCell中注册tableView,你应该在ViewDidLoad中完成,这是一个更好的解决方案。


那样做不行。 - Phil Andrews
你可能有UIView作为顶层视图,而不是UITableViewCell。 - Ivan Ičin
不,我没有。请查看添加的图片。 - Phil Andrews

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接