UITableViewCell 内容在滚动时合并
UITableViewCell content merging on scrolling
当我打开 ViewController 时,我可以看到具有正确内容的普通 UITableView,如下图所示
当我尝试上下滚动时,突然内容合并如下图所示。
请帮我解决这个问题
我的密码是
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [[announcement valueForKey:@"title"] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
UILabel *label = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"cell"];
}
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
[[cell contentView] addSubview:label];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
if (!label)
label = (UILabel*)[cell viewWithTag:1];
label.textColor = [UIColor colorWithRed:93.0/255.0 green:93.0/255.0 blue:93.0/255.0 alpha:1.0];
label.font = [UIFont fontWithName:kFontHelveticaNeueBold size:cell.textLabel.font.pointSize];
label.text=[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text =[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
请帮忙
问题可能是因为单元格重复使用。使用 tableView 单元格的最佳方法是自定义单元格。然后你不需要在 cellForRowAtIndexPath:
.
中添加 UI 元素
为了在您当前的代码中即时解决,在重用的情况下删除现有的子视图,
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
当您使用可重复使用的单元格时,对于每个单元格天气它是可重复使用的或新创建的,您正在创建一个新标签并将其添加到单元格的内容视图上。
对于新创建的单元格,添加标签不是问题。
但是,当单元格被重复使用时会出现问题,该单元格已经包含一个标签,并且再次创建了另一个标签,该标签覆盖了前一个标签,因此导致一个标签与另一个标签重叠。
要解决此问题,您有两个选择-
1) 使用当前索引路径的标签数据更新可重用单元格标签的内容
2) 如果是可重复使用的单元格,则释放之前的标签并创建一个新标签,使用当前行的数据进行初始化。
使用第二种方法,我已将您的单元格创建处理程序的实现更新为 -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
UILabel *label = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"cell"];
}
label = [[cell contentView] viewWithTag:indexPath.row];
if(label ! = nil)
[label removeFRomSuperView];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:indexPath.row];
[[cell contentView] addSubview:label];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
label.textColor = [UIColor colorWithRed:93.0/255.0 green:93.0/255.0 blue:93.0/255.0 alpha:1.0];
label.font = [UIFont fontWithName:kFontHelveticaNeueBold size:cell.textLabel.font.pointSize];
label.text=[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
[label release];
return cell;
}
您可以使用上述实现来解决由于可重复使用的单元格上存在多个标签而导致的重叠问题。
当我打开 ViewController 时,我可以看到具有正确内容的普通 UITableView,如下图所示
当我尝试上下滚动时,突然内容合并如下图所示。
我的密码是
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [[announcement valueForKey:@"title"] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
UILabel *label = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"cell"];
}
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
[[cell contentView] addSubview:label];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
if (!label)
label = (UILabel*)[cell viewWithTag:1];
label.textColor = [UIColor colorWithRed:93.0/255.0 green:93.0/255.0 blue:93.0/255.0 alpha:1.0];
label.font = [UIFont fontWithName:kFontHelveticaNeueBold size:cell.textLabel.font.pointSize];
label.text=[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text =[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
请帮忙
问题可能是因为单元格重复使用。使用 tableView 单元格的最佳方法是自定义单元格。然后你不需要在 cellForRowAtIndexPath:
.
为了在您当前的代码中即时解决,在重用的情况下删除现有的子视图,
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
当您使用可重复使用的单元格时,对于每个单元格天气它是可重复使用的或新创建的,您正在创建一个新标签并将其添加到单元格的内容视图上。
对于新创建的单元格,添加标签不是问题。
但是,当单元格被重复使用时会出现问题,该单元格已经包含一个标签,并且再次创建了另一个标签,该标签覆盖了前一个标签,因此导致一个标签与另一个标签重叠。
要解决此问题,您有两个选择-
1) 使用当前索引路径的标签数据更新可重用单元格标签的内容
2) 如果是可重复使用的单元格,则释放之前的标签并创建一个新标签,使用当前行的数据进行初始化。
使用第二种方法,我已将您的单元格创建处理程序的实现更新为 -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
cell.backgroundColor=[UIColor clearColor];
UILabel *label = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"cell"];
}
label = [[cell contentView] viewWithTag:indexPath.row];
if(label ! = nil)
[label removeFRomSuperView];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:indexPath.row];
[[cell contentView] addSubview:label];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
label.textColor = [UIColor colorWithRed:93.0/255.0 green:93.0/255.0 blue:93.0/255.0 alpha:1.0];
label.font = [UIFont fontWithName:kFontHelveticaNeueBold size:cell.textLabel.font.pointSize];
label.text=[[announcement valueForKey:@"title"] objectAtIndex:indexPath.row];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
[label release];
return cell;
}
您可以使用上述实现来解决由于可重复使用的单元格上存在多个标签而导致的重叠问题。