iOS 表视图单元格不显示预期行为



>昨天我问了一个关于单元格没有正确显示依赖于字符串值的按钮的问题。如果需要,请查看它: 具有核心数据的表视图上的奇怪行为。

用户@jrturton指出以下内容作为他回答的一部分:

重用的单元格每次都会添加子视图 - 因此可以 是许多紧急的观点相互叠加。细胞应该只永远 添加一次并将其保留在属性中

我认为这个答案标志着我必须遵循的正确方向来解决我的问题,但我无法将答案实现到我的代码中,如下所示:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObject *managedObject = [fetchedResultsController   objectAtIndexPath:indexPath];
    NSString *isUrgent = [[managedObject valueForKey:@"urgent"]description];

    [[cell textLabel] setText:[[managedObject valueForKey:@"thingName"] description]];

    //urgent
    if ([isUrgent isEqual:@"Urgent"]){
    UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
    [urgentButton setImage:[UIImage imageNamed:@"urgent-3"]forState:UIControlStateNormal];
    [cell addSubview:urgentButton];
        NSLog(isUrgent);
    }
    //not urgent 
    if ([isUrgent isEqual:@"Not urgent"]){
        UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
        [urgentButton setImage:[UIImage imageNamed:nil]forState:UIControlStateNormal];
        [cell addSubview:urgentButton];
        NSLog(isUrgent);
    }

    [[cell detailTextLabel] setText:@"  "];
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    cell.textLabel.textColor = [UIColor blueColor];
    cell.textLabel.font = [UIFont fontWithName:@"Noteworthy" size:22.0f];
    cell.detailTextLabel.font = [UIFont fontWithName:@"Noteworthy" size:15.0f];
}

单元的行为必须遵循:

1. If isUrgent = @"Urgent", the cell must show urgentButton (including imageNamed:@"urgent-3":
2. Else no button has to be shown.

当前行为如下:

1. If isUrgent = @"Urgent", the cell shows urgentButton (including imageNamed:@"urgent-3".
2. If isUrgent = @"Not urgent", value tested in NSLog, the cell shows urgentButton too.

仅当单元格至少更改了一次其紧急值时,才会发生此行为。

我需要您的帮助来实现上述答案。谢谢。

我同意@wuii,但我认为答案可以更清楚。 这个想法是,重用的单元格已经构建了它们的视图层次结构,因此每次重用单元格时(滚动期间的所有时间)再次执行此操作是有害的。 该建议可以封装在返回单元格紧急按钮的"懒惰获取器"中。

// above @implementation
#define kURGENT_BUTTON_TAG  (256)
- (UIButton *)urgentButtonInCell:(UITableViewCell *)cell {
    UIButton *urgentButton = (UIButton *)[cell viewWithTag:kURGENT_BUTTON_TAG];
    if (!urgentButton) {
        urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)];
        urgentButton.tag = kURGENT_BUTTON_TAG;
        [cell addSubview:urgentButton];
    }
    return urgentButton;
}

现在,您的配置单元只需请求按钮:

UIButton *urgentButton = [self urgentButtonInCell:cell];
UIImage *image = ([isUrgent isEqualToString:@"Urgent"])? [UIImage imageNamed:@"urgent-3"] : nil;
[urgentButton setImage:image forState:UIControlStateNormal];

您需要跟踪您的单元格是否重复使用或它是新鲜的。

这里可能发生的情况是,您正在将UIButton添加到重用的单元格中,但它已经具有具有"紧急-3"图像集的按钮

这样做

  1. 再传递一个 BOOL 参数以配置单元格 isFreshCell,其值是否设置为每个新单元格。

**

MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
isFreshCell = NO;
if(cell==nil)
{
 isFreshCell = YES;
 cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
} 
[self configureCell:cell atIndexPath:indexPath isFreshCell:isFreshCell];

新方法签名

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath isFreshCell:(BOOL) isFreshCell

2 当您添加按钮时,请为其设置一些标签。

3 如果isFreshCell为假,请不要添加新按钮,因为它已经存在,您可以使用像cell.contentView.subviewWithTag这样的subviewWithTag方法访问此按钮,然后设置图像或设置nil图像或只是隐藏按钮

最新更新