0

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

我美丽的图画

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

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

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

4

2 回答 2

0

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

于 2013-09-20T18:24:18.880 回答
0

我在这里有一些工作代码可以完成您尝试做的事情。只需确保backgroundColor将 UIView 设置为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

于 2013-09-30T16:36:13.610 回答