Label in custom cell is null when populating UITab

2019-07-31 02:11发布

问题:

I'm using Xamarin.iOS to build an iOS app. I'm using a storyboard and have created a UITableViewController with a grouped table using custom cells. The cell contains a label to which I want to assign a value.

Overriding the getcell method in the datasource to set the text property of the label throws a null exception and I can't find why? I've checked the outlet and it's there. Any tips on how to find the error?

public partial class NameListScreen : UITableViewController
{
    MyTableSource _source = null;

    public override void ViewWillAppear (bool animated)
    {
        base.ViewWillAppear (animated);

        LoadNameList();          
    }

    void LoadNameList ()
    {
        var service = new MyService();
        var names = service.GetAllNames();

        _source = new MyTableSource(names);

        this.TableView.Source = _source;
    }
}

public class MyTableSource : UITableViewSource {

    protected List<string> _names;
    protected string _cellIdentifier = "MyCell";

    public MyTableSource (List<string> items)
    {
        _names = items;
    }

    public override int RowsInSection (UITableView tableview, int section)
    { 
        return _names.Count;
    }

    public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
        // Request a recycled cell to save memory
        var cell = (MyTableCell) tableView.DequeueReusableCell(_cellIdentifier);

        // If there are no cells to reuse, create a new one
        if (cell == null)
        cell = new MyTableCell();

        cell.UpdateCell(indexPath, _names[indexPath.Item]);

        return cell;
    }
}


public partial class MyTableCell : UITableViewCell
{

    public MyTableCell () : base ()
    { }

    public MyTableCell (IntPtr handle) : base (handle)
    { }

    public void UpdateCell(NSIndexPath indexPath, string name)
    {
        this._indexPath = indexPath;
        this._id = track.TrackId;
        this.NameLabel.Text = name;   //This row throws exception as NameLabel is null, why? 
    }
}

回答1:

Based on your question I think you did not load the xib in the correct manner. Inside you custom cell just put a static method like the following.

// Inside MyTableCell
public static MyTableCell Create()
{
    NSArray topLevelObjects = NSBundle.MainBundle.LoadNib("MyTableCell", null, null);
    MyTableCell cell = Runtime.GetNSObject(topLevelObjects.ValueAt(0)) as MyTableCell;
    return cell;
}

This pattern is now used in new Xamarin cell creation template. The only difference is that UINib class is used (I can't verify it since I don't have Xamarin Studio with me).

Then, in GetCell method you should do like the following

public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
    // Request a recycled cell to save memory
    var cell = (MyTableCell) tableView.DequeueReusableCell(_cellIdentifier);

    // If there are no cells to reuse, create a new one
    if (cell == null)
        cell = MyTableCell.Create();

    cell.UpdateCell(indexPath, _names[indexPath.Item]);
    return cell;
}

You need to [Register("MyTableCell")] in .cs for using in XIB if you haven't registered it yet. You also need to set the type of the designed cell as MyTableCell in your XIB file.

But, play a bit with Xamarin template (you can choose them if you create a new iOS file) and you will find a custom cell template.