简体   繁体   English

有条件地在UITableViewCell中显示图像

[英]Conditionally display image in UITableViewCell

I'm trying to display an image in only certain cells in my UITableView. 我正在尝试仅在UITableView中的某些单元格中显示图像。 Here's a my configureCell method: 这是我的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;
    }
}

And here's cellForRowAtIndexPath: 这是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;
}

This doesn't quite work because at first, all of the cells draw them ribbonView, regardless of the value of info.visited . 这并不完全有效,因为首先,所有单元将它们绘制为ribbonView,而与info.visited的值info.visited I've stepped through the if/else and I see that the hiding code it being hit, though. 我已经逐步了解了if / else,但是看到了隐藏代码。 But, if I navigate away from the list, and then come back, the correct ribbon state is visible. 但是,如果我离开列表,然后再返回,则可以看到正确的功能区状态。 Scrolling the table view breaks it again. 滚动表格视图会再次使其中断。

The font colors are always correct, though. 字体颜色始终是正确的。

If you are reusing cells, then it could likely be that you are adding multiple ribbonView subviews to the cell, so even if the info.visited for the current indexPath is NO , there is another ribbonView leftover on the cell that you can still see. 如果您正在重用的细胞,那么它有可能成为你添加多个ribbonView子视图的细胞,所以即使info.visited当前indexPathNO ,对,你仍然可以看到该小区的其他ribbonView剩。

The thing to do is make certain you only ever have one ribbonView subview, which can be done either by removing old ribbonViews in your configuration method, or better by subclassing UITableViewCell and adding a ribbonView property to the cell, which gets set once and added to the cell's view hierarchy once, and which you can then access and set hidden to NO or YES in the configuration method. 要做的事情是确保您只有一个ribbonView子视图,这可以通过在配置方法中删除旧的ribbonViews来实现,也可以通过对UITableViewCell进行子类化并向该单元格添加ribbonView属性来更好地完成,该属性只需设置一次并添加到单元格的视图层次结构一次,然后可以访问它,然后在配置方法中将其hiddenNOYES

EDIT: The cell text color will always be correct since you are changing the color on one instance of UILabel that is in the cell's view hierarchy. 编辑:单元格文本颜色将始终是正确的,因为您正在更改单元格视图层次结构中的UILabel实例上的颜色。 I expect you'd see the same buggy behavior if instead your configuration method added a new UILabel subview to the cell each time it was configured. 如果您的配置方法每次配置时都向该单元格添加一个新的UILabel子视图,我希望您会看到相同的错误行为。

EDIT: Code to try 编辑:代码尝试

-(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;
    }
}

If you are using dequeueReusableCellWithIdentifier:forIndexPath: in the tableView:cellForRowAtIndexPath: method. 如果在tableView:cellForRowAtIndexPath:方法中使用dequeueReusableCellWithIdentifier:forIndexPath: Every time you reutilize a cell, you will create a new UIImageView and put it over the last one. 每次重新使用一个单元格时,都将创建一个新的UIImageView并将其放在最后一个单元格上。

But to solve this you dont need to subclass. 但是要解决这个问题,您不需要子类化。 Not yet, because your cells are simple still. 还没有,因为您的细胞仍然很简单。 If you want to add more subviews, then subclassing is the only option. 如果要添加更多子视图,则子类化是唯一的选择。

One solution I can think of would be this: 我能想到的一种解决方案是:

-(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;
    }
}

Try it and tell me if it works. 试试看,告诉我是否可行。

Good luck. 祝好运。

That is definitely an issue in implementation of 这绝对是实施中的一个问题

tableView:cellForRowAtIndexPath:

You need to always call 你需要经常打电话

dequeueReusableCellWithIdentifier:forIndexPath:

and then call your configure method 然后调用您的configure方法

configureCell:atIndexPath:(NSIndexPath *)indexPath

EDIT: 编辑:

Also, I think you also need to do [cell.contentView addSubView:...] instead of [cell addSubView:...] 另外,我认为您还需要执行[cell.contentView addSubView:...]而不是[cell addSubView:...]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM