高度不同的分组UITableView行会导致内容混乱
我尽了最大努力先在这里找到答案,但我被卡住了。我有一个UITableView集合,其中UITableViewStyle由4个部分组成,每个部分有一行或两行。在其中的两个部分中,我需要一个更高的行来容纳我粘贴的内容 看起来不错,但当我上下滚动时,文本标签、附件和额外的子视图开始转移到不同的行中,我不知道为什么 这显示了加载时的表视图,然后在我上下滚动几次之后。每次我滚动不同的行内容时都会出现混乱 我想我读到一些关于这是一个分组风格的问题。果不其然,如果我将表格样式更改为默认样式,我不会看到这个问题。使用分组样式时,是否不允许动态设置某些行的高度高度不同的分组UITableView行会导致内容混乱,uitableview,Uitableview,我尽了最大努力先在这里找到答案,但我被卡住了。我有一个UITableView集合,其中UITableViewStyle由4个部分组成,每个部分有一行或两行。在其中的两个部分中,我需要一个更高的行来容纳我粘贴的内容 看起来不错,但当我上下滚动时,文本标签、附件和额外的子视图开始转移到不同的行中,我不知道为什么 这显示了加载时的表视图,然后在我上下滚动几次之后。每次我滚动不同的行内容时都会出现混乱 我想我读到一些关于这是一个分组风格的问题。果不其然,如果我将表格样式更改为默认样式,我不会看到这个问题
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == kSection_Info && indexPath.row == kSectionRow_InfoPhoto)
{
return 84.0;
}
else if (indexPath.section == kSection_Level && indexPath.row == kSectionRow_LevelLevel)
{
return 70.0;
}
return 44.0;
}
我正在celForRowAtIndexPath中手动设置每一行:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"RecipientEntryCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
switch (indexPath.section)
{
case kSection_Info:
{
switch (indexPath.row)
{
case kSectionRow_InfoName:
{
cell.textLabel.text = @"Name";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(74, 8, 195, 25)];
self.nameLabel.textAlignment = UITextAlignmentRight;
self.nameLabel.font = [UIFont systemFontOfSize:16];
self.nameLabel.textColor = [UIColor blueColor];
self.nameLabel.text = self.currentRecipient.fullName;
[cell.contentView addSubview:self.nameLabel];
break;
}
case kSectionRow_InfoPhoto:
{
cell.textLabel.text = @"Photo";
self.imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.imageButton.frame = CGRectMake(10, 14, 64, 64);
[self.imageButton addTarget:self action:@selector(onImageButtonTouch:) forControlEvents:UIControlEventTouchUpInside];
NSString *imageName = @"add_image.png";
UIImage *thumb = [UIImage imageNamed:imageName];
[self.imageButton setImage:thumb forState:UIControlStateNormal];
cell.accessoryView = self.imageButton;
break;
}
default:
{
break;
}
}
break;
}
case kSection_List:
{
switch (indexPath.row)
{
case kSectionRow_ListHasList:
{
cell.textLabel.text = @"Is Listed";
self.listSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = self.listSwitch;
break;
}
case kSectionRow_ListBudget:
{
cell.textLabel.text = @"List Amount";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
self.budgetLabel = [[UILabel alloc] initWithFrame:CGRectMake(124, 8, 145, 25)];
self.budgetLabel.textAlignment = UITextAlignmentRight;
self.budgetLabel.font = [UIFont systemFontOfSize:16];
self.budgetLabel.textColor = [UIColor blueColor];
self.budgetLabel.text = [@"$" stringByAppendingFormat:@"%0.2f", [self.currentRecipient.budget floatValue]];
[cell.contentView addSubview:self.budgetLabel];
break;
}
default:
{
break;
}
}
break;
}
case kSection_Level:
{
switch (indexPath.row)
{
case kSectionRow_LevelLevel:
{
self.levelSlider = [[UISlider alloc] initWithFrame:CGRectMake(8, 2, 284, 40)];
self.levelSlider.minimumValue = 0.0;
self.levelSlider.maximumValue = 100.0;
self.levelSlider.continuous = YES;
UIImage *meterImage = [UIImage imageNamed:@"meter_labels.png"];
UIImageView *meterView = [[UIImageView alloc] initWithFrame:CGRectMake(8, 32, 284, 24)];
[meterView setImage:meterImage];
[cell.contentView addSubview:self.levelSlider];
[cell.contentView addSubview:meterView];
[meterImage release];
break;
}
case kSectionRow_LevelHasLevel:
{
cell.textLabel.text = @"Show Level";
self.levelSwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryView = self.levelSwitch;
break;
}
default:
{
break;
}
}
break;
}
case kSection_RecipientDelete:
{
cell.textLabel.text = @"Delete Recipient";
cell.textLabel.textAlignment = UITextAlignmentCenter;
cell.textLabel.textColor = [UIColor blueColor];
break;
}
default:
{
break;
}
}
}
return cell;
}
您看到的“内容混乱”很可能是由于对单元格重复使用的不当处理
分组样式没有特别的问题。问题更可能以这种方式表现出来,因为屏幕中容纳的单元格更少,需要更多的滚动,需要更多的单元格重复使用
您仅在创建单元格时设置单元格内容(当单元格==nil时)。当一个单元格从屏幕上滚下时,它进入重用队列。现在可见的另一端的行重新使用重复使用队列中的单元格视图。重复使用的单元格包含其他行的内容
当所有单元格都相似时(至少在UI控件而不是数据方面),这不是问题。当所有或部分单元格都不同时,您会看到控件出现在您不希望它们出现的位置
因为您只有少量的行,并且每个行的布局都不同,所以快速(可能是脏的)解决方案是为每个单元格使用不同的重用标识符,如下所示:
NSString *CellIdentifier =
[NSString stringWithFormat:@"RecipientEntryCell-%d-%d",
indexPath.section, indexPath.row];
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCell...
if (cell == nil) {
//Create cell...
//Set UI content that applies to all rows (if any)...
}
else {
//Cell is being re-used.
//Remove UI content that doesn't apply to this row...
}
//Add UI content that applies only to this row...
//Copy values from data source to cell UI controls...
return cell;
如果表视图将有许多不同的单元格,则不建议这样做,因为表中每行的每个单元格都将同时在内存中(而不仅仅是屏幕上的少数单元格)不要使用唯一标识符来解决任何和所有单元格重复使用问题。
《表视图编程指南》显示了一种类似于这样设计表视图的替代方法,其中有几个单元格具有不同的布局。请参阅上的“静态行内容的技术”
最终,如果您了解表视图有充分的理由重复使用单元格,而不是一直试图绕过它,那就更好了。通常,CellForRowatineXpath应如下所示:
NSString *CellIdentifier =
[NSString stringWithFormat:@"RecipientEntryCell-%d-%d",
indexPath.section, indexPath.row];
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCell...
if (cell == nil) {
//Create cell...
//Set UI content that applies to all rows (if any)...
}
else {
//Cell is being re-used.
//Remove UI content that doesn't apply to this row...
}
//Add UI content that applies only to this row...
//Copy values from data source to cell UI controls...
return cell;
如果如上所示构造单元格,请不要在单元格内维护对UI控件(如nameLabel、imageButton等)的类级引用。相反,应在cellForRowAtIndexPath中从备份数据变量(模型)中设置控件值,并应在UI控件更改后立即将该值读取或保存回备份数据变量
例如,与其在单元格中存储对UISlider的引用,不如将当前滑块值存储为float ivar。在适当的地方初始化浮动(例如viewDidLoad)。在cellForRowAtIndexPath中,创建UISlider,使用float ivar设置其值,并让滑块在其值更改时调用方法。在该方法中,将滑块的值复制到float ivar
希望这有帮助。您的
tableView:cellforrowatinexpath:
方法是什么样子的?将其添加到我的问题中,谢谢!非常感谢您的详细回复。我在试着调试时做了一些测试,并且意识到了同样的事情。我当前的问题与表格样式或行高无关。这一切都与我不知道用不同的静态内容构建表的正确方法有关。我真的只想要用于布局和样式的表,所以我不介意在IB中构建唯一的单元格。我也会接受您关于避免类级引用的建议