在它的 Superview 中掩盖视图的路径以显示它的 SuperSupervView

Posted

技术标签:

【中文标题】在它的 Superview 中掩盖视图的路径以显示它的 SuperSupervView【英文标题】:Mask a View's Path in It's Superview To Reveal It's SuperSupervView 【发布时间】:2013-09-20 18:05:13 【问题描述】:

我试图弄清楚如何根据子视图的路径掩盖视图的路径以显示底层视图。我不确定我是否能 100% 清楚地表达我想要做什么,所以这是我画的一张照片:

为了进一步阐明和推动这一点 - 视图 3 是视图 2 的子视图。视图 2 是视图 1 的子视图。视图 3 具有清晰的背景,显示视图 1。

我希望能够根据视图 2 的子视图动态屏蔽该区域。所以 - 在视图 2 的 drawRect 中 - 我希望能够调查其子视图,获得它们的帧,并将视图 2 屏蔽到这些帧。

我对 ios/Objective-c 的其余部分并不太了解,但我仍然倾向于 Core Graphics 并且无法完全弄清楚这一点。任何帮助将非常感激。

【问题讨论】:

【参考方案1】:

一种简单的方法可能是让视图 2 像没有子视图一样绘制自身,然后在每个子视图帧中迭代调用 NSEraseRect 的子视图。请注意,视图 3 必须完全透明(即不绘制任何内容)才能正常工作。

【讨论】:

【参考方案2】:

我这里有一些工作代码可以执行您尝试执行的操作。只需确保将 UIView 的 backgroundColor 设置为 clearColor

这是drawRect: 方法:

- (void)drawRect:(CGRect)rect 
    [[UIColor purpleColor] setFill];

    CGContextRef context = UIGraphicsGetCurrentContext();

    for (UIView *subview in self.subviews) 
        CGContextAddPathWithRect(context, subview.frame, NO);
    
    CGContextAddPathWithRect(context, rect, YES);
    CGContextFillPath(context);

本质上,这里发生的事情是我们为子视图创建了一堆逆时针路径,然后我们创建了一个大路径顺时针当前视图的框架。然后,由于奇偶规则,它只会对视图中未被子视图覆盖的部分着色。

我创建了这个函数CGContextAddPathWithRect 以使代码更清晰、更易于阅读。这是它的实现:

void CGContextAddPathWithRect(CGContextRef context, CGRect rect, BOOL clockwise) 
    CGFloat x, y, width, height;
    x = rect.origin.x; y = rect.origin.y;
    width = rect.size.width; height = rect.size.height;
    if (clockwise) 
        CGContextMoveToPoint(context, x, y);
        CGContextAddLineToPoint(context, x + width, y);
        CGContextAddLineToPoint(context, x + width, y + height);
        CGContextAddLineToPoint(context, x, y + height);
     else 
        CGContextMoveToPoint(context, x + width, y + height);
        CGContextAddLineToPoint(context, x + width, y);
        CGContextAddLineToPoint(context, x, y);
        CGContextAddLineToPoint(context, x, y + height);
    
    CGContextClosePath(context);

这是我创建的测试项目的 zip 链接:SOHoleSubviews.zip

【讨论】:

以上是关于在它的 Superview 中掩盖视图的路径以显示它的 SuperSupervView的主要内容,如果未能解决你的问题,请参考以下文章

当内部按钮触摸时,如何从 Superview 中删除以编程方式创建的子视图?

从 nib 加载视图尊重 superview 的顶部布局指南(导航栏底部)

iOS Autolayout如何在superview中拉伸子视图

如何引用superview的navigationController

关于 subview 在 Objective-C 中保留 superview 的问题

调用 Selector 方法时未从 Superview 中删除视图