Как использовать пользовательский UITableViewCell из Interface Builder?

Я хочу быть в состоянии разработать свой собственный UITableViewCell в IB. Но я продолжаю получать исключение null ref при попытке получить доступ к метке, которую я определил в IB.

Вот что я делаю:

В Интерфейсном Разработчике:

  • Я удалил "View" и вместо этого добавил UITableViewCell.
  • Изменен класс UITableViewCell на "TestCellView".
  • Добавлен UILabel в ячейку.
  • Добавлена ​​розетка "oLblText"чтобы TestCellView и подключил 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 для каждой ячейки. Я видел несколько примеров в Интернете, делающих это. Я просто думаю, что это полное излишество.

Что я делаю неправильно?

3 ответа

Решение

Прежде всего, это вопрос дизайна. Если ваше табличное представление всегда загружает определенное количество ячеек со статическим содержимым, как в представлении "Настройки", создайте настраиваемую ячейку для каждой строки, которую вы хотите, и подключите каждую из них к розетке.

Если это не так, то у вас есть два варианта:

  1. Создайте класс, который наследует UITableViewCell и все нужные вам представления программно, забывая Interface Builder.
  2. Добавьте новый iPhone View с Controller, замените его там и относитесь к нему так же, как вы. За исключением того факта, что вам придется подключить вашу ячейку к розетке в Владельце файла. Поэтому, когда вы создадите экземпляр этого контроллера, все подпредставления вашей ячейки будут в порядке.

Это не перебор, или, по крайней мере, Apple рекомендует это: нажмите и перейдите к пункту "Загрузка пользовательских ячеек табличного представления из файлов пера"

PS: Просто была похожая ситуация, и я так и сделал. В MonoTouch для этого примера вам не нужно LoadNib что-нибудь. Просто сделайте это внутри переопределения GetCell в источнике вашей таблицы:

using (CellController controller = new CellController())
{

     cell = (CustomCell)controller.View;

}

Может быть, даже объявить дополнительную розетку внутри CellController объект, чтобы избежать приведения из UIView.

Вы не можете ссылаться ни на какие розетки, пока не будет загружено перо. Существует метод, который вы можете переопределить, который скажет вам: "Ваш NIB загружен, теперь вы можете получить доступ к полям". До этого момента ссылка на эти объекты всегда будет возвращать ноль.

Проверьте эту ссылку. Это очень интересная статья для создания пользовательского TableViewCell. Я думаю, что ошибка связана с асинхронной загрузкой XIB, предоставленной Monotouch.

Вы должны предоставить свой собственный конструктор, как это:

public TestCellView(string sKey) //: base(UITableViewCellStyle.Default, sKey)
{
    MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("YOUR NIBNAME", this, null);
}

Надеюсь это поможет!

Другие вопросы по тегам