Monotouch: правильный способ повторно использовать UITableViewCell - PullRequest
4 голосов
/ 16 апреля 2011

Я выясняю правильный способ повторного использования ячеек в UITableView, и я бы знал, правильный ли механизм, который я использую,

Сценарий следующий.

У меня есть UITableView, который отображает список данных, полученных из веб-службы.

_listOfItems = e.Result as List<Item>;

где _listOfItems - переменная экземпляра.

Этот список передается в класс, который расширяет UITableViewSource. Очевидно, этот класс переопределяет метод GetCell для визуализации данных следующим образом:

public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{       
    UITableViewCell cell = tableView.DequeueReusableCell(_cID);

    Item item = _listOfItems[indexPath.Row];

    int id = item.Id;

    if (cell == null)
    {   
        cell = new UITableViewCell(UITableViewCellStyle.Value1, _cID);

        cell.Tag = id;

        _cellControllers.Add(id, cell);
    }
    else
    {
        bool vb = _cellControllers.TryGetValue(id, out cell);

        if(vb)
        {
            cell = _cellControllers[id];
        }

        else
        {
            cell = new UITableViewCell(UITableViewCellStyle.Value1,  _cID);             
            cell.Tag = id;

            _cellControllers.Add(id, cell);
        }
    }

    cell.TextLabel.Text = item.Title;

    return cell;
}

, где

_cID - идентификатор переменной экземпляра для ячейки

string _cID = "MyCellId";

_cellControllers - это словарь для хранения ячейки и относительного идентификатора для экземпляра Item

Dictionary<int, UITableViewCell> _cellControllers;

Я использую словарь для хранения ячеек, потому что при постукивании строки мне нужно получить идентификатор для прослушиваемой ячейки (через значение cell.Tag), выполнить какую-то другую операцию - т.е. извлечь другие данные из службы - и затем обновите эту ячейку снова новыми значениями . В этом случае каждая ячейка должна быть уникальной.

Итак, мой вопрос:

Является ли это правильным способом повторного использования ячейки, или можно найти другое решение для повторного использования ячейки и гарантировать, что каждый ответ для ячейки уникален?

Надеюсь, все понятно :) Заранее спасибо. С уважением.

Ответы [ 2 ]

8 голосов
/ 16 апреля 2011

Я думаю, что вы делаете здесь, это слишком много.Особенно часть, где вы держите дополнительные ссылки на ячейки в Словаре.

Я бы сделал это по-другому.Существует метод DequeueReusableCell, так что вы можете извлечь любую существующую ячейку, но не обязательно значения, которые она содержит.Так что примерно такого будет достаточно:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{

    int rowIndex = indexPath.Row;
    Item item  = _listOfItems[rowIndex];

    UITableViewCell cell = tableView.DequeueReusableCell(_cID);

    if (cell == null)
    {
        cell = new UITableViewCell(UITableViewCellStyle.Value1, _cID);
    }

    // Store what you want your cell to display always, not only when you are creating it.
    cell.Tag = item.ID;
    cell.TextLabel.Text = item.Title;

    return cell;
}

Затем в методе RowSelected измените ваш источник данных:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath){
    // Do something here to change your data source _listOfItems[indexPath.Row] = new Item();
}

Если я правильно понимаю, что вы хотите сделать, это решениелучше.

5 голосов
/ 17 апреля 2011

Вы избавите себя от многих проблем, если будете использовать мою библиотеку MonoTouch.Dialog, которая позаботится обо всех этих деталях и сделает именно то, что вы хотите, и даже больше. Это позволит вам сосредоточиться на своем приложении, а не на администрировании, и я верю, что вы сможете двигаться быстрее, вы можете получить его из:

http://github.com/migueldeicaza/MonoTouch.Dialog

Первая проблема с этим кодом заключается в том, что он жестко кодирует ячейки одного типа. Как правило, вам нужно сначала проверить раздел / строку и на основе этой информации определить тип ячейки, которую вы хотите.

Как только вы определили тип ячейки, которую вы хотите, затем вы используете эту информацию для вызова DequeueReusableCell с токеном, связанным с этим идентификатором ячейки. Это отличается, например, для ячейки, которая содержит строку ввода, по сравнению с ячейкой, которая содержит изображение. Вам нужно вычеркнуть нужную клетку.

Вам не нужно делать каждую ячейку уникальной, вся необходимая информация находится в разделе / ​​строке, так что вам нужно что-то, что сопоставляет раздел / строку с вашей уникальной ячейкой. Простой подход состоит в том, что есть один раздел, а строка - это индекс в массив данных, из которого вы хотите получить больше информации.

Небольшое руководство по передовым методам создания этих ячеек можно найти здесь:

http://tirania.org/monomac/archive/2011/Jan-18.html

Если вы использовали MonoTouch.Dialog, весь ваш код мог бы быть:

var elements = "foo, bar, baz";
var dvc = new DialogViewController ();
dvc.Root = new RootElement ("My results") {
    from x in elements.Split (',')
        select (Element) new StringElement (x);
};
dvc.Root.Add ("Final one");

current.PresentModalViewController (dvc, true);

Вышеприведенное создает UITableView с 4 строками, по одному для «foo», «bar» и «baz», используя Linq, и добавляет дополнительный узел в конце, просто чтобы показать, как использовать API Add.

Есть также много разных элементов, которые вы можете использовать, вы не ограничены только элементами String.

...