xcode CAShapeLayer 蒙版视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20090038/
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-09-15 04:19:01  来源:igfitidea点击:

CAShapeLayer mask view

iosxcodemaskcashapelayer

提问by Marko Zadravec

I have one problem. I look for the answers on the net and I don't understand why is not working. I must do some stupid mistake which I can't figure it out.

我有一个问题。我在网上寻找答案,但我不明白为什么不起作用。我必须犯一些我无法弄清楚的愚蠢错误。

if I make :

如果我做:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView * view = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 300, 400)];
    view.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view];

}

it create blue view on the screen, but if I make

它在屏幕上创建蓝色视图,但如果我让

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView * view = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 300, 400)];
    view.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view];

    CAShapeLayer * layer = [[CAShapeLayer alloc]init];
    layer.frame = CGRectMake(10, 10, 30, 30);
    layer.fillColor = [[UIColor blackColor] CGColor];

    view.layer.mask = layer;

}

it don't show anything.

它不显示任何内容。

If I understand correctly it should mask at (10,10,30,30)?

如果我理解正确,它应该在 (10,10,30,30) 处屏蔽?

回答by cncool

You need to set the path on the CAShapeLayer:

您需要在 CAShapeLayer 上设置路径:

- (void)viewDidLoad
{
    [super viewDidLoad];


    UIView * view = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 300, 400)];
    view.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view];

    CAShapeLayer * layer = [[CAShapeLayer alloc]init];
    layer.frame = view.bounds;
    layer.fillColor = [[UIColor blackColor] CGColor];

    layer.path = CGPathCreateWithRect(CGRectMake(10, 10, 30, 30), NULL);

    view.layer.mask = layer;
}

回答by Eugene Tartakovsky

Thanks for the answer, cncool.

感谢您的回答,cncool。

In case someone can't find suitable answer on SO for this question for hours, like i just did, i've assembled a working gist in Swift 2.2 for masking/clippingUIViewwith CGRect/UIBezierPath:

如果有人在这个问题上几个小时都找不到合适的答案,就像我刚刚做的那样,我已经在 Swift 2.2 中为masking/clippingUIViewCGRect/组装了一个工作要点UIBezierPath

https://gist.github.com/Flar49/7e977e81f1d2827f5fcd5c6c6a3c3d94

https://gist.github.com/Flar49/7e977e81f1d2827f5fcd5c6c6a3c3d94

extension UIView {
    func mask(withRect rect: CGRect, inverse: Bool = false) {
        let path = UIBezierPath(rect: rect)
        let maskLayer = CAShapeLayer()

        if inverse {
            path.appendPath(UIBezierPath(rect: self.bounds))
            maskLayer.fillRule = kCAFillRuleEvenOdd
        }

        maskLayer.path = path.CGPath

        self.layer.mask = maskLayer
    }

    func mask(withPath path: UIBezierPath, inverse: Bool = false) {
        let path = path
        let maskLayer = CAShapeLayer()

        if inverse {
            path.appendPath(UIBezierPath(rect: self.bounds))
            maskLayer.fillRule = kCAFillRuleEvenOdd
        }

        maskLayer.path = path.CGPath

        self.layer.mask = maskLayer
    }
}

Usage:

用法:

let viewSize = targetView.bounds.size
let rect = CGRect(x: 20, y: 20, width: viewSize.width - 20*2, height: viewSize.height - 20*2)

// Cuts rectangle inside view, leaving 20pt borders around
targetView.mask(withRect: rect, inverse: true)

// Cuts 20pt borders around the view, keeping part inside rect intact
targetView.mask(withRect: rect)

Hope it will save someone some time in the future :)

希望它会在将来为某人节省一些时间:)