用切出的圆圈遮住 UIView [英] Mask a UIView with a cut-out circle

查看:23
本文介绍了用切出的圆圈遮住 UIView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个带有半透明黑色背景的 UIView 来放置在我的主应用程序的视图上.我在这里的目标是在 UIView 的某个地方创建一个切出的圆形形状,在那里看不到半透明的黑色背景,在整个图像上产生黑色蒙版的效果,除了圆形区域(这是为了突出显示该区域中的按钮).

I’ve created a UIView with a semi-transparent black background to sit across my main app’s view. What I’m aiming for here is to create a cut-out circle shape somewhere in that UIView where the semi-transparent black background is not seen, giving the effect of a black mask over the whole image except the circular area (this is to highlight a button in that area).

我已经设法使用 CAShapeLayer 来创建一个圆形蒙版,但这产生了相反的效果(即视图的其余部分是清晰的,并且圆圈内部是半透明的黑色.我想要的是圆圈外的所有东西都保持半透明的黑色,那么里面的东西要清楚.这是我使用的代码,我该如何让它以相反的方式工作?我的blackMask 是半透明的黑色视图,我的 buttonCircle 是我希望保持清晰的圆圈.

I’ve managed to use CAShapeLayer to create a circular mask, but this has had the opposite effect (i.e. the rest of the view is clear, and INSIDE the circle is the semi-transparent black. What I’d like is everything outside of the circle to keep the semi-transparent black, then what’s inside to be clear. Here’s the code I used, how would I go about making it work in the opposite way? My blackMask is the semi-transparent black view, and my buttonCircle is the circle I’d like to be kept clear.

也许我需要以某种方式反转路径?

Perhaps I need to invert the path, somehow?

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGRect maskRect = buttonCircle.frame;
CGPathRef path = CGPathCreateWithEllipseInRect(maskRect, NULL);
maskLayer.path = path;
CGPathRelease(path);
blackMask.layer.mask = maskLayer;

现在试试这个,用这个根本看不到任何面具:

Trying this now, not seeing any mask at all with this one:

UIView *circularMaskView = [[UIView alloc] initWithFrame:buttonCircle.frame];
circularMaskView.backgroundColor = [UIColor greenColor];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];

CGPathRef path = CGPathCreateWithEllipseInRect(buttonCircle.frame, NULL);
maskLayer.path = path;
CGPathRelease(path);

circularMaskView.layer.mask = maskLayer;

[blackMask addSubview:circularMaskView];

推荐答案

所以,这就是我所做的.我创建了一个名为 BlackoutView 的自定义 UIView 子类,如下所示:

So, here’s what I did. I created a custom UIView subclass called BlackoutView, like so:

BlackoutView.h

#import <UIKit/UIKit.h>

@interface BlackoutView : UIView

@property (nonatomic, retain) UIColor *fillColor;
@property (nonatomic, retain) NSArray *framesToCutOut;

@end

BlackoutView.m

#import "BlackoutView.h"

@implementation BlackoutView

- (void)drawRect:(CGRect)rect
{
    [self.fillColor setFill];
    UIRectFill(rect);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(context, kCGBlendModeDestinationOut);

    for (NSValue *value in self.framesToCutOut) {
        CGRect pathRect = [value CGRectValue];
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:pathRect];
        [path fill];
    }

    CGContextSetBlendMode(context, kCGBlendModeNormal);
}

@end

然后我像往常一样实例化它,并将属性设置为我想要使用的蒙版的颜色,以及要从蒙版中切出的帧:

I then instantiate it as normal, and set the properties to the colour of the mask I want to use, and the frames to be cut out of the mask:

[blackMask setFillColor:[UIColor colorWithWhite:0.0f alpha:0.8f]];
[blackMask setFramesToCutOut:@[[NSValue valueWithCGRect:buttonCircleA.frame],
                               [NSValue valueWithCGRect:buttonCircleB.frame]]];

这可以通过允许我切出除椭圆之外的其他形状来改进,但这对我的目的来说很好,以后很容易适应这样做.希望这对其他人有帮助!

This could be improved by allowing me to cut out other shapes besides ovals, but it’s fine for my purposes here and would be easily adapted to do so later. Hopefully this helps others!

这篇关于用切出的圆圈遮住 UIView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆