Overlapping UITableViewCell content views

2020-02-26 13:06发布

I have this table whose cells look like this: UITabelViewCell
As you can see, the top border of every cell is supposed to overlap with the cell above. Right now, this border is part of the background (no overlapping so far).

Now, I've separated the border from the background and my cell creation code looks like this:

#define QAImage(NAME) [[[UIImageView alloc] initWithImage:[UIImage imageNamed:NAME]] autorelease]

- (UITableViewCell*) tableView:(UITableView*)table cellForRowAtIndexPath:(NSIndexPath*)index
{
    UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:@"Entry"];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                         reuseIdentifier:@"Entry"] autorelease];
        cell.backgroundView = QAImage(@"bg-cell.png");
        cell.selectedBackgroundView = QAImage(@"bg-cell-sel.png");
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
        UIImageView *img = QAImage(@"disclosure.png");
        img.highlightedImage = [UIImage imageNamed:@"disclosure-sel.png"];
        cell.accessoryView = img;
        CGRect r = cell.frame;
        r.size.height = table.rowHeight;
        r.size.width = table.frame.size.width;
        cell.frame = r;
        r = cell.contentView.frame;
        r.origin = CGPointMake(13, 13);
        r.size.width -= 8 + img.frame.size.width;
        r.size.height -= 25;
        [cell.contentView addSubview:[[[TagView alloc] initWithFrame:r] autorelease]];
        img = QAImage(@"cell-top.png");
        img.highlightedImage = [UIImage imageNamed:@"cell-top-sel.png"];
        img.opaque = NO;
        r = img.frame;
        r.origin = CGPointMake(0, 1 - r.size.height); // The (supposed) overlapping happens here.
        img.frame = r;
        cell.contentView.clipsToBounds = NO;
        [cell.contentView addSubview:img];
    }
    // Here I set the title. (omitted)
    return cell;
}

The problem is, the border is only shown when I'm scrolling up in the table, else it is itself overlapped by the cell above it. (The wrong way around.)

I've tried [cell setNeedsDisplay] in -tableView:willDisplayCell:forRowAtIndexPath:, adding the border (cell-top.png) every time a cell is requested (which obviously leads to multiple drawing and doesn't look good; regardless, it still doesn't solve my problem) and setting img.layer.zPosition = 2.

How can I force that UIImageView to stay on top all the time?

1条回答
一纸荒年 Trace。
2楼-- · 2020-02-26 14:10

My suggestion would be to subclass UITableView and override layoutSubviews to put the visible cell views into the z-order you want them to be in like this:

- (void)layoutSubviews {
    [super layoutSubviews];
    NSArray *sortedIndexPaths = [[self indexPathsForVisibleRows] sortedArrayUsingSelector:@selector(compare:)];
    for (NSIndexPath *path in sortedIndexPaths) {
        UITableViewCell *cell = [self cellForRowAtIndexPath:path];
        [self bringSubviewToFront:cell];
    }
}

This might be too slow, or you might need to change bringSubviewToFront: to sendSubviewToBack:, but hopefully that gives you a direction to try out.

EDIT: Another option now, if you're targeting iOS 6, is to use a UICollectionView instead, which has built-in support for z-ordering.

查看更多
登录 后发表回答