【问题标题】:Monotouch: The correct way to reuse a UITableViewCellMonotouch:重用 UITableViewCell 的正确方法
【发布时间】:2011-08-06 20:36:53
【问题描述】:

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

场景如下。

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

_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 实例的相对 id

Dictionary<int, UITableViewCell> _cellControllers;

我正在使用字典来存储单元格,因为当点击一行时,我必须检索所点击单元格的 ID(通过 cell.Tag 值),执行一些其他操作 - 即从服务中检索其他一些数据- 然后用新值再次更新该单元格。在这种情况下,每个单元格都必须是唯一的。

所以,我的问题是:

这是重用单元格的正确方式,还是有可能找到另一种解决方案来重用单元格并保证单元格的每次点击都是唯一的?

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

【问题讨论】:

    标签: uitableview xamarin.ios reusability


    【解决方案1】:

    如果您使用我的 MonoTouch.Dialog 库,您会为自己省去很多麻烦,该库会为您处理所有这些细节并完全按照您的意愿进行操作等等。它会让你专注于你的应用程序而不是专注于管理,我相信会让你行动更快,你可以从:

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

    此代码的第一个问题是它将单元格硬编码为单一类型。通常,您必须首先检查部分/行,然后根据此信息确定您想要的单元格类型。

    一旦确定了所需的单元格类型,您就可以使用此信息调用 DequeueReusableCell,并使用与此单元格 ID 关联的令牌。例如,对于包含输入行的单元格与包含图像的单元格,这是不同的。您需要将正确类型的单元格出列。

    您不需要使每个单元格都是唯一的,您需要的所有信息都在节/行中,因此您需要将节/行映射到您的唯一单元格的东西。一种简单的方法是,只有一个部分,行是​​您要从中获取更多信息的数据数组的索引。

    可以在此处找到有关创建这些单元的最佳实践的小教程:

    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);
    

    上面使用 Linq 创建了一个有 4 行的 UITableView,其中一行用于“foo”、“bar”和“baz”,并在最后添加了一个额外的节点来展示如何使用 Add API。

    你也可以使用许多各种各样的元素,你不仅限于字符串元素。

    【讨论】:

      【解决方案2】:

      我觉得你在这里做的有点过分了。尤其是您对字典中的单元格进行额外引用的部分。

      我会做不同的事情。 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();
      }
      

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

      【讨论】:

      • 谢谢迪米特里斯。我认为这可能是一个更好的解决方案。在这种情况下,当您滚动表格时,会从头开始创建或重复使用单元格,但标签会根据 indexpath.row 进行更改。不是真的吗?
      • 是的。刚刚编辑了 RowSelected 方法。您甚至不必检索单元格,因为它的标签已设置为项目的 ID。因此,您可以直接从列表中的项目中检索 id。我想说的是直接使用您的数据源并根据它们的工作处理单元格:显示数据而不是其他任何内容。
      • 另一件事:单元格不是从头开始创建的。单元格被创建一次。每次都根据数据源分配其内容。实际上,您甚至不必分配单元格的标签。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 2021-09-06
      • 1970-01-01
      相关资源
      最近更新 更多