如果超出父视图边界,iOS7的子视图会被修剪[重复]

Posted

技术标签:

【中文标题】如果超出父视图边界,iOS7的子视图会被修剪[重复]【英文标题】:iOS7's subview trimmed if out of parent view bounds [duplicate] 【发布时间】:2013-09-18 09:43:12 【问题描述】:

我翻阅了来自 Apple 的新 UI 信息 - 没有帮助。

现在让代码和屏幕截图向您展示我遇到的问题。 为了确保这不是我的错误代码,我创建了一个新项目,其中包含一个文件 - 一个 UIViewController,它的 ID 内有一个 tableView。代表已设置。

我执行以下操作:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView


    // Return the number of sections.
    return 3;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section


    return 3;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"UITableViewCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    
    cell.textLabel.text = [NSString stringWithFormat:@"%d",indexPath.row];
    // Configure the cell...

    UIView * redView = [[UIView alloc] initWithFrame:CGRectMake(0, -10, 100, 20)];
    redView.backgroundColor = [UIColor redColor];
    [cell addSubview:redView];

    return cell;

表格视图设置为分组。 让我们在 ios 6 上运行它:

当然,Y 原点是负的! 是的,是的,这就是我想要达到的结果。 让我们看看它在 iOS 7 上显示的内容:

提示:如果我们将 redView 添加到普通 UIView,则不会发生这种情况。

另一个提示:如果我将 tableView 的背景颜色设置为蓝色,则部分之间的灰色线将是蓝色,而不是灰色(作为灰色不是设置标题的演示)。 另一个提示:ipad 也是如此。

为什么在 iOS 7 中它会删除所有超出范围的内容?请帮忙!

【问题讨论】:

您是否尝试将单元格的clipsToBounds 属性设置为NO? 是的..它没有用,但谢谢你的提示。 【参考方案1】:

这是因为 iOS 7 对 UITableViewCells 的视图层次结构进行了一些更改。

它曾经是UITableViewCell view -> contentView

现在它更像UITableViewCell view -> scrollView -> contentView

解决方法是在scrollView上设置clipsToBounds = NO(默认设置为YES)。而实现这一点的方法是通过superview 属性。

所以基本上在 iOS6 和之前的版本中,为了让内容溢出单元格边界,你会这样做:

self.clipsToBounds = NO;                        //cell's view
self.contentView.clipsToBounds = NO;            //contentView

在 iOS7 中,您还必须防止滚动视图不被剪切,因此您可以执行以下操作:

self.clipsToBounds = NO;                        //cell's view
self.contentView.clipsToBounds = NO;            //contentView
self.contentView.superview.clipsToBounds = NO;  //scrollView

我使用的向后兼容的解决方案是:

self.clipsToBounds = NO;
self.contentView.clipsToBounds = NO;
if ([self.contentView.superview isKindOfClass:[NSClassFromString(@"UITableViewCellScrollView") class]]) self.contentView.superview.clipsToBounds = NO;

请记住,这是 Hacky™,如果 iOS 8 中视图层次结构再次发生变化,您可能会遇到麻烦。不幸的是,Apple 似乎不希望我们从 UITableViewCells 中溢出内容,所以 AFAIK 这是唯一可行的解​​决方案。

【讨论】:

【参考方案2】:

以下将解决它:

cell.layer.masksToBounds = NO

但是,它可能会破坏其他东西,例如单元格动画。

您遇到的问题是由于单元格不支持绘制超出其边界的内容(实际上,使用扩展其父视图边界的子视图始终是一个 hacky 解决方案)。

最好的建议是重新设计并完全避免这种功能性。

另一种解决方案是将相同的视图添加到前一个单元格的底部,或者直接将它们添加为UITableView 的子视图。

【讨论】:

masktobounds 根本不起作用,在自定义单元格类初始化方法和 cellforrow tableView 数据源方法中都尝试过...我正在尝试遵循您的最佳建议并通过 headerforsection 数据源正确执行方法。但仍在等待,也许有人会针对所描述的情况提出解决方案......【参考方案3】:

我不认为内容实际上是在masksToBounds-sense 中修剪的,而是视图被其他(不透明)单元格覆盖。您可以尝试通过更改UITableView 的子视图的顺序(“z-Index”)来修复它,每当出现单元格时使用bringSubviewToFront: 和类似方法,以确保单元格最靠近屏幕底部边缘是所有单元格的最前面的视图。

【讨论】:

考虑到这是问题所在,我已经尝试了许多修复方法,但没有奏效。不过,感谢您的宝贵时间! @Theo 您正确地发现了问题,但不幸的是bringSubviewToFront 没有解决它。它只将子视图放在单元格的 contentView 中,而不是整个 tableView。意思是,覆盖单元格的 UITableViewCell 仍然保留在前面

以上是关于如果超出父视图边界,iOS7的子视图会被修剪[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用 CardView 动画视图超出父布局边界

在 iOS 7 中,状态栏出现在我的视图边界上 [重复]

让超出父视图范围的子视图响应事件,在UIView范围外响应点击

【iOS】UIButton超出父视图点击无效(swift)

如何在被父视图部分裁剪的子视图上触发 UITapGestureRecognizer?

SwiftUI任意继承层级中视图被裁剪显示不全的解决方案