ios iPhone - 在 UIView 上绘制透明矩形以显示下面的视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3800278/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:47:54  来源:igfitidea点击:

iPhone - Draw transparent rectangle on UIView to reveal view beneath

iosiphoneuiviewquartz-graphics

提问by Dave

I currently have two UIViews: one of a red background and the other blue. The blue view is a subview of the red view. What I would like to do is be able to "cut" out rectangles on the blue view so that the red view can be visible. How do you go about doing this?

我目前有两个 UIViews:一个是红色背景,另一个是蓝色。蓝色视图是红色视图的子视图。我想要做的是能够在蓝色视图上“剪切”出矩形,以便可以看到红色视图。你打算怎么做?

回答by Jacques

You have to override the top view's drawRectmethod. So, for example, you might create a HoleyViewclass that derives from UIView(you can do that by adding a new file to your project, selecting Objective-C subclass, and setting "Subclass of" to UIView). In HoleyView, drawRectwould look something like this:

您必须覆盖顶视图的drawRect方法。因此,例如,您可以创建一个HoleyView派生自的类UIView(您可以通过向项目添加一个新文件,选择 Objective-C 子类,并将“子类 of”设置为UIView)。在HoleyView,drawRect看起来像这样:

- (void)drawRect:(CGRect)rect {
    // Start by filling the area with the blue color
    [[UIColor blueColor] setFill];
    UIRectFill( rect );

    // Assume that there's an ivar somewhere called holeRect of type CGRect
    // We could just fill holeRect, but it's more efficient to only fill the
    // area we're being asked to draw.
    CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );

    [[UIColor clearColor] setFill];
    UIRectFill( holeRectIntersection );
}

If you're using Interface builder, make sure to change the holey view's class to HoleyView. You can do that by selecting in the view in Interface Builder and selecting the "Identity" pane in the inspector (its the one on the far right the the "i" icon).

如果您使用的是界面构建器,请确保将有孔视图的类更改为HoleyView. 您可以通过在 Interface Builder 的视图中选择并在检查器中选择“身份”窗格(最右侧的“i”图标)来实现。

You also have to set the top view to be non-opaque either with the following code snippet, or by un-checking the Opaquecheckbox in the view's properties in Interface Builder (you'll find it in the View section of the view's attributes) and set its background color's opacity to 0% (background color is set in the same section).

您还必须使用以下代码片段将顶视图设置为非不透明,或者通过取消Opaque选中 Interface Builder 中视图属性中的复选框(您将在视图属性的“视图”部分中找到它)和将其背景颜色的不透明度设置为 0%(背景颜色在同一部分设置)。

topView.opaque = NO;
topView.backgroundColor = [UIColor clearColor];

If you want to do circles, you have to use Core Graphics(aka Quartz 2D). You'll probably want to read the programming guide, which is available here.

如果你想做圆圈,你必须使用Core Graphics(又名 Quartz 2D)。您可能想要阅读编程指南,可在此处获得

To draw an ellipse instead of the rectangle, your drawRectwould look something like this:

要绘制椭圆而不是矩形,您drawRect将看起来像这样:

- (void)drawRect:(CGRect)rect {
    // Get the current graphics context
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor( context, [UIColor blueColor].CGColor );
    CGContextFillRect( context, rect );

    if( CGRectIntersectsRect( holeRect, rect ) )
    {
        CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
        CGContextFillEllipseInRect( context, holeRect );
    }
}

回答by rage

There is truth in all the other answers, but it is quite possible to draw with clear colour, or so to say erasethe existing colours within any path, even with the -[UIBezierPath fill] or similar convenience methods. All you have to do is to set the context blend mode to an appropriate value depending on the effect you are trying to achieve, like so:

所有其他答案都有道理,但很可能用 clear color 绘制,或者说擦除任何路径中的现有颜色,即使使用 -[UIBezierPath fill] 或类似的便利方法。您所要做的就是根据您要实现的效果将上下文混合模式设置为适当的值,如下所示:

CGContextSetBlendMode(context, kCGBlendModeClear);
[[UIColor clearColor] set];
[myArbitraryPolygonPath fill];

There are around two dozen different options you could choose from, take a look around the CGContext reference.

您可以选择大约两打不同的选项,请查看CGContext 参考

回答by valvoline

to draw an ellipse, instead of a rect, just set the blendMode to clear:

要绘制椭圆而不是矩形,只需将 blendMode 设置为 clear:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor( context, [UIColor blackColor].CGColor );
    CGContextFillRect( context, rect );

    CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );

    CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
    CGContextSetBlendMode(context, kCGBlendModeClear);

    CGContextFillEllipseInRect( context, holeRect );
}

回答by Adam Eberbach

These may be the dumb ways but I would not do it the way you describe, but make it look the way you want it to look.

这些可能是愚蠢的方式,但我不会按照你描述的方式去做,而是让它看起来像你想要的样子。

(Jacques' answer just popped up - looks good to me)

(雅克的回答刚刚出现 - 对我来说看起来不错)

Approach 1: In the view controller to build a list of rectangles that tile around the exposed "hole". As your holes increase in number the number of tiling rects will also increase.

方法 1:在视图控制器中构建一个矩形列表,这些矩形围绕暴露的“洞”平铺。随着您的孔数量增加,平铺矩形的数量也会增加。

Approach 2: Reverse your thinking. The blue view should be at the back with sections of the red view placed on top of it. You still see a red view with all but the "holes" masked by the blue view, but what you are really doing is copying regions from the view you want to expose and putting them on top of the mask as you make each hole. If you have some effect simulating depth you could add that as required with each hole.

方法二:反转你的想法。蓝色的看法应该是放置在它上面的红色视图的部分后面。您仍然会看到一个红色视图,除了被蓝色视图掩盖的“孔”之外的所有内容,但您真正要做的是从要暴露的视图中复制区域,并在制作每个孔时将它们放在蒙版的顶部。如果你有一定的效果模拟深度可以添加一个与每个孔需要。

Neither requires subclassing or drawRect:.

两者都不需要子类化或 drawRect:。