我有一个UITableViewSource,我已经将其子类化了。我正在重写GetCell并使用我自己的子类化单元格,如下所示:
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
MarketItem item=_tableItems[indexPath.Section].Items[indexPath.Row];
MarketCell cell=tableView.DequeueReusableCell(_cellIdentifier) as MarketCell;
if (cell==null)
{
cell=new MarketCell(UITableViewCellStyle.Subtitle,_cellIdentifier,item);
}
// decorate the cell
// ...
return cell;
}
这样可行但是当我在UITableViewDelegate中获取事件时,索引路径会让我得到错误的单元格(如AccessoryButtonTapped,WillSelectRow等事件)。
截面和行数看起来正确但是当我做
时 tableView.CellAt(indexPath)
我得错了。 (行和节号再次看起来是正确的。)
注意事项:
我不禁想到这是我自己制作的一个愚蠢的错误,却无法找到它。非常感谢任何帮助!
答案 0 :(得分:1)
您可以尝试使用不同的方法,如http://simon.nureality.ca/?p=91
所示基本上,不要将UITableViewCell子类化,而是将UIViewController子类化为“MarketCellController”。这个自定义控制器维护一个标准的UITableViewCell以及你的自定义东西,只需通过AddSubview()添加你的自定义东西。
您为每个必需的单元格创建一个新控制器,并将它们存储到字典中。
技巧:通过为单元格分配唯一标记,您可以从字典中检索关联的控制器。
快速举例:
Dictionary<int,MarketCellController> controllers = new Dictionary<int,MarketCellController>();
// ...
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) {
UITableViewCell cell = tableView.DequeueReusableCell(_cellIdentifier);
MarketCellController cellController;
if (cell == null) {
cellController = new MarketCellController();
cell = cellController.Cell;
controllers.Add(cell.Tag, cellController);
} else {
cellController = controllers[cell.Tag];
}
// Decorate the cell (using Methods of your cellController)
// ...
return cell;
}
这最终可以避免子类化UITableViewCells和出列的问题。
修改强>
我只是想到了其他的东西:你似乎只是在你的MarketCell构造函数上分配你的项目。但是,出列的单元格设置了旧项目,您需要在出列后将其重置为新项目。
删除构造函数的item参数(无论如何都会被覆盖)并创建一个公共属性(或setter)。用于在获取单元格后分配正确的项目(无论它是否已出列或新创建)。应该这样做:
MarketCell cell = tableView.DequeueReusableCell(_cellIdentifier) as MarketCell;
if (cell == null) {
cell = new MarketCell(UITableViewCellStyle.Subtitle, _cellIdentifier);
}
// Assign the correct item
cell.Item = item;
// or (whatever you like more):
// cell.SetItem(item);
// Decorate the cell
// ...
return cell;
我的cellController方法也是如此。无论一个单元格是否已经出列或是新单元格,您都应该重置单元格中可能与其他单元格不同的所有内容。
BTW:如果您将单元格硬编码为UITableViewCellStyle.Subtitle,您也可以从构造函数中省略它并将其硬编码到MarketCell类中。
至于cellController方法的价值:您可以将UITableViewCell与自定义数据和行为分离,从而获得一个很好的分离层。您的单元控制器不必像表格单元格那样;)
答案 1 :(得分:0)
看来这仍然是Xamarin的一个问题。不幸的是,@ vlad259发布的链接很久就消失了 - 这个'bug'今天就让我感到厌烦。我不知道它为什么会发生 - 为了追查原因,我已经将我的UITableViewSource实现一直向下切换到返回固定数量的行,并简单地将行号分配给单元格标签。 ..
该bug特别表现为,加载视图,滚动到第一个屏幕外单元格(即,如果您的表格可以渲染10个单元格,滚动以便第11个刚出现在屏幕上),然后点击该单元格 - 您将获得RowSelected事件中几乎随机的Row索引。
我找到了几个解决方案。
解决方案A
如果我覆盖了GetHeightForRow
以返回自定义行高,即使它返回常量,这个错误也只会显示出来。如果不需要......不要覆盖它。
解决方案B
该错误似乎是DequeueReusableCell
(s)内的NSIndexPath
参数。
使用
UITableView.DequeueReusableCell(NSString)
而不是
UITableView.DequeueReusableCell(NSString, NSIndexPath)