我正在找出在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值),执行其他操作 - 即从服务中检索其他一些数据 - 然后再次使用新值更新该单元格。在这种情况下,每个单元格必须是唯一的。
所以,我的问题是:
这是重用单元格的正确方法还是可以找出另一种重用单元格的解决方案并保证单元格的每次点击都是唯一的?
我希望一切都清楚:)提前谢谢你。问候。
答案 0 :(得分: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;
}
然后,在RowSelected方法中,更改数据源:
public override void RowSelected (UITableView tableView, NSIndexPath indexPath){
// Do something here to change your data source _listOfItems[indexPath.Row] = new Item();
}
如果我理解你想做什么,这个解决方案会更好。
答案 1 :(得分: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);
上面创建了一个包含4行的UITableView,一行用于使用Linq的“foo”,“bar”和“baz”,最后添加了一个额外的节点,以显示如何使用Add API。
您可以使用许多各种元素,但不限于String元素。