将大于 cellHeight 的子视图添加到 UITableViewCell?

发布于 2024-09-01 12:43:02 字数 1144 浏览 7 评论 0原文

我正在尝试向 UITableViewCell 添加子视图,而我正在工作的设计要求这个特定的子视图(图像)需要大于实际的 UITableViewCell,从而部分重叠其兄弟视图。

因此,我设置了表格单元格,生成了图像并将其添加到单元格的 contentView 中:

// rowHeight for the UITableView is 45.0f

UIImage *image = [self createCellThumbnail: someImage];
UIImageView *thumbView = [[UIImageView alloc] initWithFrame: CGRectMake(150, -5, 55,55)];
thumbView.transform = CGAffineTransformMakeRotation(0.1f);
thumbView.image = image;

cell.clipsToBounds = NO;
cell.contentView.clipsToBounds = NO;

[cell.contentView addSubview: thumbView];

虽然图像将“溢出”到其下方的单元格中,但图像的顶部始终会被剪裁,如下所示:

img

有谁知道我正在尝试做的事情是否可以通过当前的方法实现?

或者我应该找出一种方法,在绘制所有单元格后将这些图像绘制到 UITableView 上(它是一个不可滚动的表格视图,因此可以工作并且相当容易)。

更新:

也尝试添加以下内容,但无济于事:

cell.opaque = NO;
cell.contentView.opaque = NO;

cell.clearsContextBeforeDrawing = NO;
cell.contentView.clearsContextBeforeDrawing = NO;

cell.clipsToBounds = NO;    
cell.contentView.clipsToBounds = NO;

I'm trying to add a subview to a UITableViewCell and the design that I'm working from demands that this particular subview (an image) needs to be larger than the actual UITableViewCell and thus partly overlap its siblings.

So I've set up my table cell, generated my image and added it to the cell's contentView:

// rowHeight for the UITableView is 45.0f

UIImage *image = [self createCellThumbnail: someImage];
UIImageView *thumbView = [[UIImageView alloc] initWithFrame: CGRectMake(150, -5, 55,55)];
thumbView.transform = CGAffineTransformMakeRotation(0.1f);
thumbView.image = image;

cell.clipsToBounds = NO;
cell.contentView.clipsToBounds = NO;

[cell.contentView addSubview: thumbView];

While the image will 'overflow' into the cell below it, the top of the image is always clipped, as demonstrated here:

img

Does anyone know if what I'm trying to do is possible with the current approach?

Or should I just figure out a way to draw these images onto the UITableView after all the cells are drawn (it's a non-scrollable tableview, so that would work and be fairly easy).

Update:

Have also tried adding the following, to no avail:

cell.opaque = NO;
cell.contentView.opaque = NO;

cell.clearsContextBeforeDrawing = NO;
cell.contentView.clearsContextBeforeDrawing = NO;

cell.clipsToBounds = NO;    
cell.contentView.clipsToBounds = NO;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

茶花眉 2024-09-08 12:43:02

我似乎 tableView 从下到上渲染其单元格,因此一个单元格上方的单元格与该单元格重叠。为了避免这种情况,您必须将所有单元格的 backgroundColor 设置为 +[UIColor clearColor],这样您就不会看到那些重叠问题。

但是在 -tableView:cellForRowAtIndexPath: 中将 backgroundColor 设置为清除没有任何意义。 UIKit 在绘制单元格之前对单元格执行了很多操作,因此它会重置单元格的 backgroundColor 属性。

我们需要做的是在稍后的状态中设置backgroundColor。幸运的是,我们可以像这样实现 -[UITableViewDelegate tableView:willDisplayCell:forRowAtIndexPath:]

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor clearColor];
}

现在我们在绘制单元格之前设置 backgroundColor 和 this事实证明是有效的。

I seems that the tableView renders its cell from bottom to top, so the cells above one cell overlap that one cell. To avoid this, you'd have to set the backgroundColor of all cells to +[UIColor clearColor] so that you won't see those overlap problems.

But setting the backgroundColor to clear in -tableView:cellForRowAtIndexPath: does not make any sense. UIKit does a lot of stuff with the cell before it's drawn, so does it reset the backgroundColor property of the cell.

What we need to do is setting the backgroundColor in a later state. Luckily there is this -[UITableViewDelegate tableView:willDisplayCell:forRowAtIndexPath:] which we can implement like this:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor clearColor];
}

Now we're setting the backgroundColor just before the cell is drawn an this turns out to be working.

往事随风而去 2024-09-08 12:43:02

更新:

所以我做了一些更多的实验,下面的解决方案仍然有效,无需将单元格的背景设置为透明,这涉及移动被覆盖单元格的 z 顺序。这适用于突出显示和选择另一个单元格(通过相关回调),并且如果两个单元格的背景颜色不同。解决方案如下(如果您不关心didHighlightdidSelect方法,您可以忽略它们):(

注意“覆盖行”是我们要删除其内容的行)试图保持可见,在我的情况下,其内容稍微进入上面的行,这正在剪切它)

-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
    {
        NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
        [cell.superview bringSubviewToFront:cell];
    }
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
    {
        NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
        [cell.superview bringSubviewToFront:cell];
    }
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == COVERED_ROW)
    {
        [cell.superview bringSubviewToFront:cell];
        cell.contentView.superview.clipsToBounds = NO;
    }
}

注意:您还应该将内容的背景颜色设置为清除,否则它将采用单元格其余部分的背景颜色,因此,当您设法将内容带到覆盖单元格的前面时,它将采用背景颜色,并在另一个单元格中留下一个令人讨厌的块(在我的情况下,我唯一的内容是 detailTextLabel< /code> 和 textLabel):

// in cellForRowAtIndexPath:
[cell setBackgroundColor:[UIColor redColor]]; //using red for debug
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor clearColor];

我希望这对其尝试此操作的其他人有所帮助......

原始:

对我来说,解决方案是使用:

self.contentView.superview.clipsToBounds = NO;

我的单元格已经是透明的,但我的内容仍然被剪辑。就我而言,我使用了一个自定义单元格,它将其内容在 layoutSubviews 中向上移动。因此,我的自定义单元格的 layoutSubviews 如下:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -11);
    self.contentView.superview.clipsToBounds = NO;
}

我不知道如果上面的单元格不透明,或者单元格在按下时突出显示,这是否会掩盖我的内容,这是否会起作用内容。

但是,我不需要需要在 viewWillDisplayCell 回调方法中再次使单元格透明 - 在正常的 cellForRowAtIndexPath< 中执行此操作/code> 就足够了

UPDATE:

So I've done some more experimentation and the following solution still works without having to set the background of the cell to transparent, this involved moving the z order of the covered cell. This works with highlighting and selecting of the other cell (via the relevant callbacks), and if the two cell's backgrounds are different colors. Solution is as follows (you can ignore the didHighlight and didSelect methods if they don't matter to you):

(note that "covered row" is the one whose content we are trying to keep visible and In my case its content goes slightly into the row above, which was clipping it)

-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
    {
        NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
        [cell.superview bringSubviewToFront:cell];
    }
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0 && indexPath.row == ROW_ABOVE_COVERED_ROW)
    {
        NSIndexPath * rowbelow = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:rowbelow];
        [cell.superview bringSubviewToFront:cell];
    }
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && indexPath.row == COVERED_ROW)
    {
        [cell.superview bringSubviewToFront:cell];
        cell.contentView.superview.clipsToBounds = NO;
    }
}

NOTE: you should also set the background color of your content to clear, or it will adopt the bgcolor of the rest of your cell, and so when you manage to bring your content to the front of the covering cell, it will take the background color with it and leave a nasty looking block in the other cell (in my case my only content was the detailTextLabel and the textLabel):

// in cellForRowAtIndexPath:
[cell setBackgroundColor:[UIColor redColor]]; //using red for debug
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor clearColor];

I hope that's helpful to anyone else trying this....

ORIGINAL:

For me the solution was to use:

self.contentView.superview.clipsToBounds = NO;

My cells were already transparent, but my content was still getting clipped. In my case I was using a custom cell which moves it's content up in layoutSubviews. So layoutSubviews for my custom cell wound up as follows:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.contentView.frame = CGRectOffset(self.contentView.frame, 0, -11);
    self.contentView.superview.clipsToBounds = NO;
}

I don't know if this would work if the cell above was opaque, or if the cells were to highlight when pressed, whether this would cover up my content.

However, I didn't need to make the cell transparent again in the viewWillDisplayCell callback method - doing it in the normal cellForRowAtIndexPath was sufficient

傻比既视感 2024-09-08 12:43:02

我遇到了这个问题,我确保我的自定义 tableviewcell 的主背景已检查剪辑子视图,并且它解决了问题。这是使用从 xib 加载的自定义表格视图单元格。不完全相同但相似的情况。

I had this problem and I made sure my custom tableviewcell's main background had clip subviews checked and it solved the problem. This was with a custom tableview cell loaded from a xib though. Not exactly the same but similar situation.

最美的太阳 2024-09-08 12:43:02

事实上,我昨天遇到了相反的情况,我创建了一个自定义表格单元格,由于某种原因,我得到了我不想发生的溢出。我的解决方案是将以下代码添加到我的视图控制器类中:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    return 175;
}

当它与表格单元格的高度匹配时,没有重叠;当它太小时,就会出现重叠。请注意,我的行为很快,所以我不确定这样做是不是一个好主意。

I actually had the opposite just yesterday, I had created a custom table cell and for some reason I got an overflow which I didn't want to have. My solution was to add the following code to my view controller class:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    return 175;
}

When it matched the height of the table cell there was no overlap; when it was too small there was overlap. Mind you though that I got very quicky behavious so I'm not sure it's a very good idea to do this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文