用一个切出的圆圈掩盖UIView

Luk*_*uke 16 core-animation objective-c uiview cashapelayer ios

我创建了UIView一个半透明的黑色背景,可以看到我的主应用程序视图.我在这里的目的是在一个UIView没有看到半透明黑色背景的地方创建一个切出的圆形状,除了圆形区域外,在整个图像上产生黑色遮罩的效果(这是为了突出显示)该区域的按钮).

我已经设法用来CAShapeLayer创建一个圆形面具,但这有相反的效果(即视图的其余部分是清晰的,并且圆圈内部是半透明的黑色.我想要的是除了圆圈保持半透明的黑色,然后内部清楚.这是我使用的代码,我将如何使其以相反的方式工作?我blackMask是半透明的黑色视图,我buttonCircle是圆圈我我希望保持清醒.

也许我需要以某种方式颠倒路径?

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

编辑:现在尝试这个,没有看到任何掩码与这一个:

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];
Run Code Online (Sandbox Code Playgroud)

Luk*_*uke 18

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

BlackoutView.h

#import <UIKit/UIKit.h>

@interface BlackoutView : UIView

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

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

[blackMask setFillColor:[UIColor colorWithWhite:0.0f alpha:0.8f]];
[blackMask setFramesToCutOut:@[[NSValue valueWithCGRect:buttonCircleA.frame],
                               [NSValue valueWithCGRect:buttonCircleB.frame]]];
Run Code Online (Sandbox Code Playgroud)

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


Mru*_*rug 8

如果您正在使用任何黑色图像进行屏蔽

-(void)maskWithImage:(UIImage*)maskImage toImageView:(UIImageView*)imgView{

    CALayer *aMaskLayer=[CALayer layer];
    aMaskLayer.contents=(id)maskImage.CGImage;

    imgView.layer.mask=aMaskLayer;


}
Run Code Online (Sandbox Code Playgroud)

如果要屏蔽任何Custom ShapeLayer

-(void)maskWithShapeLayer:(CALayer*)layer toImageView:(UIImageView*)imgView{
    //Layer should be filled with Black color to mask those part of Image
    imgView.layer.mask=layer;
}
Run Code Online (Sandbox Code Playgroud)

如果你想用Circle制作ImageView Mask

-(void)maskWithCircle:(UIImageView*)imgView{

    CAShapeLayer *aCircle=[CAShapeLayer layer];
    aCircle.path=[UIBezierPath bezierPathWithRoundedRect:imgView.bounds cornerRadius:imgView.frame.size.height/2].CGPath; // Considering the ImageView is square in Shape

    aCircle.fillColor=[UIColor blackColor].CGColor;
    imgView.layer.mask=aCircle;

}
Run Code Online (Sandbox Code Playgroud)


tom*_*mys 5

这是我对 Swift 中接受的答案的转换:

public class OverlayView: UIView {
let fillColor: UIColor = UIColor.grayColor()
public var framesToCutOut: Array<NSValue> = [NSValue]()

override public func drawRect(rect: CGRect) {
    super.drawRect(rect)

    fillColor.setFill()
    UIRectFill(rect)

    if let context: CGContextRef = UIGraphicsGetCurrentContext() {
        CGContextSetBlendMode(context, .DestinationOut)

        for value in framesToCutOut {
            let pathRect: CGRect = value.CGRectValue()
            let path: UIBezierPath = UIBezierPath(ovalInRect: pathRect)
            path.fill()
        }

        CGContextSetBlendMode(context, .Normal)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用其他 swift 代码调用此 swift 代码,则无需将 CGRect 放入 NSValues 中 - 只需将 frameToCutOut 设为 [CGRect] 数组即可 (2认同)