Monotouch:重用UITableViewCell的正确方法

Lor*_*o B 4 reusability uitableview xamarin.ios

我正在找出在UITableView中重用单元格的正确方法,我会知道我使用的机制是否正确.

场景如下.

我有一个UITableView,它显示从Web服务获得的数据列表.

_listOfItems = e.Result as List<Item>;
Run Code Online (Sandbox Code Playgroud)

其中_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;
}
Run Code Online (Sandbox Code Playgroud)

哪里

_cID是单元格的实例变量标识符

string _cID = "MyCellId";
Run Code Online (Sandbox Code Playgroud)

_cellControllers是一个存储单元格的字典和Item实例的相对id

Dictionary<int, UITableViewCell> _cellControllers;
Run Code Online (Sandbox Code Playgroud)

我正在使用字典来存储单元格,因为当点击一行时,我必须检索被点击的单元格的id(通过cell.Tag值),做一些其他操作 - 即从服务中获取其他一些数据 - 然后更新那个细胞再次出现新的价值观.在这种情况下,每个单元必须是唯一的.

所以,我的问题是:

这是重用单元的正确方式还是有可能找到另一种重用单元的解决方案并保证单元的每个抽头都是唯一的?

我希望一切都清楚:)提前谢谢你.问候.

Dim*_*kos 8

我觉得你在这里做的有点太多了.特别是您在字典中对单元格进行额外引用的部分.

我会做的不同.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;
}
Run Code Online (Sandbox Code Playgroud)

然后,在RowSelected方法中,更改您的数据源:

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

如果我理解你想要做什么,这个解决方案会更好.


mig*_*aza 5

如果你用我的MonoTouch.Dialog库,负责所有这些细节对你和你想要做什么和你越会为自己省下不少麻烦.它会让你专注于你的应用程序,而不是专注于administrivia,我相信会让你更快,你可以从:

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

此代码的第一个问题是,这会将单元格硬编码为单个类型.通常,您必须首先检查部分/行,并根据此信息确定所需的单元格类型.

一旦确定了所需的单元格类型,就可以使用此信息通过与此单元格ID关联的令牌调用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);
Run Code Online (Sandbox Code Playgroud)

上面创建了一个包含4行的UITableView,一个用于使用Linq的"foo","bar"和"baz",并在末尾添加了一个额外的节点,以显示如何使用Add API.

您还可以使用许多各种元素,您不仅限于String元素.