直到今天我还以为我理解了UITableView,但是由于在滚动问题时我一直在努力解决滚动和内容不匹配问题,因此感觉已经发生了变化。
我有一个小的表视图,可能有20-30行,具体取决于用户内容。当我滚动(比通常快一点)时,内容混淆了。一些附件视图互换,背景颜色被交换或覆盖;有时甚至文本都会改变。
我对某些单元格使用重用标识符,但我不确定它是否正常运行。
的问题:
显然,单个重用标识符不会将其删除 - 作为第一个和最后一个单元格交换值。
对于第一个,最后一个和剩余的单元格(包含设置)有3个重用标识符,附件视图在包含设置的某些单元格之间互换,即在某些情况下我使用开关控件,在其他情况下我使用附件细节按钮,有亵渎。
即使对不同类型的内容使用5个重用标识符,附件视图也会与其他单元格的背景颜色不匹配。
我一直在写表格视图,我以前从未遇到过这些问题。所以我有一个简单的问题 - 你什么时候创建重用标识符?
我完全迷失了,所以如果你能真正做出解释,我会非常感激。
编辑:过去5个小时我一直在研究这个问题,并且在StackOverflow上经历了大量的文献和开放/封闭问题。我理解可重复使用的细胞是什么。提供的主题不回答非常具体的问题。以下是一些代码:
// previously had 3 different types of cells; currently doing with one only
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell)
{
cell = [[ESBasicTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstCellId = @"First";
static NSString *SecondCellId = @"Second";
static NSString *ThirdCellId = @"Third";
static NSString *ForthCellId = @"Forth";
static NSString *FifthCellId = @"Fifth";
static NSString *SixthCellId = @"Sixth";
NSString *cellIdentifier = nil;
if (indexPath.section == kSectionFirst && indexPath.row == kRowFirst)
{
cellIdentifier = FirstCellId;
}
else if (indexPath.section == kSectionFirst && indexPath.row == kRowSecond)
{
cellIdentifier = SecondCellId;
}
else if (indexPath.section == kSectionSecond)
{
cellIdentifier = ThirdCellId;
}
else if (indexPath.section == kSectionThird)
{
cellIdentifier = ForthCellId;
}
else if (indexPath.section == kSectionSettings)
{
cellIdentifier = FifthCellId;
}
else if (indexPath.section == kSEctionFifth)
{
cellIdentifier = SixthCellId;
}
return cellIdentifier;
}
configureCell:atIndexPath
方法导致其他配置调用;其中一个是设置配置:
- (void)configureCellForSettings:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
cell.selectionStyle = UITableViewCellSelectionStyleNone;
switch (indexPath.row)
{
case kRowNotificationSetting:
{
cell.textLabel.text = @"Notifications";
cell.accessoryType = UITableViewCellAccessoryDetailButton;
cell.imageView.image = [[UIImage imageNamed:@"cell_notification_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
break;
}
case kRowSomeOtherSetting:
{
cell.textLabel.text = @"Auto";
cell.imageView.image = [[UIImage imageNamed:@"cell_auto_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
[switchView addTarget:self action:@selector(changed:) forControlEvents:UIControlEventValueChanged];
[switchView setOn:...];
cell.accessoryView = switchView;
break;
}
default:
break;
}
}
一些有意义的文字被删除了(不幸的是)。第四部分是设置,但这只是一个例子。
修改:此处为configureCell:atIndexPath:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == kSectionFirst)
{
// ...
[self configureFirstCell:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionSecond)
{
// ...
[self configureSecondCell:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionThird)
{
// add ...
[self configureThirdCell:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionSettings)
{
// settings
[self configureCellForSettings:cell atIndexPath:indexPath];
}
else if (indexPath.section == kSectionFifth)
{
// delete button
[self configureFifthCell:cell atIndexPath:indexPath];
}
}
请注意 - 我必须重命名很多代码才能在StackOverflow上使用它。
答案 0 :(得分:2)
我只是将其标记为副本,因为当您致电dequeueReusableCellWithIdentifier:
每当您致电dequeueReusableCellWithIdentifier:
以获取单元格时,请尝试概念化您正在返回之前生成的单元格之一,并将内容添加到具有相同标识符的 (事实上,这正是你正在做的事情)。这样返回的单元格可能已经有附件视图/图像集等,您可能需要根据用例取消设置/删除它们。
如果您有多个类型的单元格(布局/内容显着不同),那么您可能需要考虑使用多个重用标识符 - 每种类型的单元格的重用标识符,这样您就可以每次重复使用单元格时,都可以轻松地重复使用单元格,而不是重置所有附件视图/图像/等。