clipsToBounds 是如何工作的?

Posted

技术标签:

【中文标题】clipsToBounds 是如何工作的?【英文标题】:How does clipsToBounds work? 【发布时间】:2013-12-25 07:13:33 【问题描述】:

我想知道如何使用UIView 属性clipsToBounds

官方文档是这样说的:

clipsToBounds属性

一个布尔值,用于确定子视图是否被限制在 视图的边界。

讨论 将此值设置为 YES 会导致子视图被剪切到 接收器的边界。如果设置为NO,则其框架扩展的子视图 超出接收器的可见边界不会被剪裁。默认 值为NO

但我不清楚这究竟意味着什么。我应该如何使用clipsToBounds?将此属性设置为YES 的后果是什么?或者NO

【问题讨论】:

【参考方案1】:

这是一个简洁的快速答案与公认的答案

如果 Apple 要重命名此属性,我将其命名为:clipSubviewsToBounds

我刚刚在我们的代码中遇到了一个错误。父视图的高度设置为0。 我们希望看不到它的任何元素/子视图。然而父视图的子视图却出现了。

这是因为 clipToBounds 未设置为 true。一旦将其设置为true,那么子视图的高度就不能超出0,一旦它们达到其父视图的高度,它们就会被剪裁。在这种情况下,它们会在0 处被截断,即它们根本不显示。

当您使用 Xcode 的“Debug View Hierarchy”调试视图时,了解这一点很有帮助。然后您可以选择 显示剪辑的内容 并查看子视图是否被剪辑到其父视图的边界。例如如果您的子视图的宽度为 250,但超级视图只有 200,那么一旦您切换它,您将看到额外的 50 个点被剪裁/隐藏。

【讨论】:

这个答案被低估了【参考方案2】:

如果我的超级视图是一个每边测量 10 个单位的盒子,而我的子视图是 20 个单位宽,clipsToBounds 设置为 YES,我只会看到子视图中符合范围的部分超级视图。否则,如果clipsToBounds 设置为NO,我将看到整个子视图,甚至是父视图之外的部分(假设我们仍在屏幕上)。

作为一个视觉示例,请考虑在故事板上设置的以下视图:

这是一个白色的UIView,左上角的标签带有简单的“1”或“2”,因此我可以将它们讨论为view1view2。此外,黑色视图与白色视图的大小相同,但它的原点位于白色视图的中心。

在视图控制器的viewDidLoad方法中,我们有如下代码:

目标-C:

- (void)viewDidLoad 
    [super viewDidLoad];
    self.view1.clipsToBounds = YES;
    self.view2.clipsToBounds = NO;

斯威夫特:

override func viewDidLoad() 
    super.viewDidLoad()
    self.view1.clipsToBounds = true
    self.view2.clipsToBounds = false

当我们运行代码并在模拟器或设备上查看时,我们得到以下结果:

因此,尽管这些视图的设置相同(clipsToBounds 除外),但它们看起来却不同。这就是clipsToBounds 所做的。将其设置为 YES 将提供顶部结果,而将其设置为 NO 将提供底部结果。

如果我们调试视图层次结构,我们可以更清楚地看到黑框实际上都超出了白色视图的边界,但只有视图 2 在应用程序实际运行时显示:

【讨论】:

绝妙的答案!做得好。但我有一个问题。为什么UITextView 阴影不可见,如果clipsToBounds 属性等于true; ?如果是false,就可以了 注意:您将 clipsToBounds 更改为父视图。因此,如果 viewB 是 viewA 的子视图。需要使 clipsToBounds 为 true 的 viewA。 从该视图上的原始视图框架显示的哪个视图是轻击手势有效,因为我检查它并不起作用。

以上是关于clipsToBounds 是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

GestureRecognizer 开始时如何以编程方式关闭 clipsToBounds 属性?

NSView如何实现类似于UIView中的clipsToBounds功能(即不切割其SubView)

在 iOS8 中使用 clipsToBounds = YES 时,状态栏完全变黑。我该如何改变?

如何删除圆形 UIImageView 中的空白?

自定义单元格中的 UIImageView 无法正常工作

具有多个彩色边框的圆形UIView像饼图一样工作