2

我试图在 UITableView 的某些单元格中显示图像。这是我的 configureCell 方法:

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    StoryInfo *info = [self.fetchedResultsController objectAtIndexPath:indexPath];
    UIImage *ribbon = [UIImage imageNamed:@"ribbon.png"];
    UIImageView *ribbonView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
    [ribbonView setImage:ribbon];
    [cell addSubview:ribbonView];
    if([[NSNumber numberWithBool:NO] isEqualToNumber:info.visited]) {
        cell.textLabel.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1];
        ribbonView.hidden = NO;
    }
    else {
        cell.textLabel.textColor = [UIColor colorWithRed:128.0/255.0 green:128.0/255.0 blue:128.0/255.0 alpha:1.0];
        ribbonView.hidden = YES;
    }
}

这是 cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // set up the cell...
    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

这并不完全奏效,因为起初,所有单元格都将它们绘制为ribbonView,而不管info.visited. 我已经通过了 if/else 并且我看到了它被击中的隐藏代码。但是,如果我离开列表,然后返回,则可以看到正确的功能区状态。滚动表格视图会再次破坏它。

不过,字体颜色总是正确的。

4

3 回答 3

5

如果您正在重用单元格,那么很可能您正在向ribbonView单元格添加多个子视图,因此即使info.visited当前indexPathNO,单元格上仍有另一个ribbonView 剩余,您仍然可以看到。

要做的事情是确保您只有一个ribbonView子视图,这可以通过ribbonViews在配置方法中删除旧的来完成,或者通过子类化UITableViewCell并向单元格添加ribbonView属性来更好地完成,该属性被设置一次并添加到单元格的视图层次结构中一次,然后您可以访问并设置hiddenNOYES在配置方法中。

编辑:单元格文本颜色将始终正确,因为您正在更改UILabel单元格视图层次结构中的一个实例的颜色。UILabel如果您的配置方法在每次配置时向单元格添加一个新的子视图,我希望您会看到相同的错误行为。

编辑:代码尝试

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    static NSInteger ribbonTag = 12345;
    StoryInfo *info = [self.fetchedResultsController objectAtIndexPath:indexPath];
    // re-use a ribbonView if one's already been added to this cell
    UIImageView *ribbonView = [cell.contentView viewWithTag:ribbonTag];
    if (!ribbonView){
       ribbonView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
       ribbonView.tag = ribbonTag;
       UIImage *ribbon = [UIImage imageNamed:@"ribbon.png"];
       [ribbonView setImage:ribbon];
       // add subviews to contentView
       [cell.contentView addSubview:ribbonView];
    }
    if([[NSNumber numberWithBool:NO] isEqualToNumber:info.visited]) {
        cell.textLabel.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1];
        ribbonView.hidden = NO;
    }
    else {
        cell.textLabel.textColor = [UIColor colorWithRed:128.0/255.0 green:128.0/255.0 blue:128.0/255.0 alpha:1.0];
        ribbonView.hidden = YES;
    }
}
于 2013-03-16T16:41:59.847 回答
1

如果你dequeueReusableCellWithIdentifier:forIndexPath:tableView:cellForRowAtIndexPath:方法中使用。每次重新使用一个单元格时,您都会创建一个新的 UIImageView 并将其放在最后一个上。

但是要解决这个问题,您不需要子类化。还没有,因为你的细胞仍然很简单。如果你想添加更多的子视图,那么子类化是唯一的选择。

我能想到的一种解决方案是:

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    StoryInfo *info = [self.fetchedResultsController objectAtIndexPath:indexPath];

    UIImageView *ribbonView = nil;

    //My code:
    for ( UIView *childView in cell.subviews ) {
        if([childView isKindOfClass:[UIImageView class]] {
            ribbonView = childView;
            break;
        }
    }
    //Note: this doesnt work if you have more than one UIImageView in your cell. 
    if(ribbonView == nil) {
        UIImage *ribbon = [UIImage imageNamed:@"ribbon.png"];
        ribbonView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
        [ribbonView setImage:ribbon];
        [cell addSubview:ribbonView];
    }
    //Ends here.

    if([[NSNumber numberWithBool:NO] isEqualToNumber:info.visited]) {
        cell.textLabel.textColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1];
        ribbonView.hidden = NO;
    }
    else {
        cell.textLabel.textColor = [UIColor colorWithRed:128.0/255.0 green:128.0/255.0 blue:128.0/255.0 alpha:1.0];
        ribbonView.hidden = YES;
    }
}

试试看,告诉我它是否有效。

祝你好运。

于 2013-03-16T17:20:41.717 回答
0

这绝对是实施中的一个问题

tableView:cellForRowAtIndexPath:

你需要经常打电话

dequeueReusableCellWithIdentifier:forIndexPath:

然后调用您的配置方法

configureCell:atIndexPath:(NSIndexPath *)indexPath

编辑:

另外,我认为您还需要做[cell.contentView addSubView:...]而不是 [cell addSubView:...]

于 2013-03-16T16:55:45.767 回答