使用CAShapeLayer和UIBezierPath剪辑屏蔽uiview

Apr*_*ram 8 objective-c uiview cashapelayer ios uibezierpath

我在使用CAShapeLayer-UIBezierPath剪切视图时遇到问题,我想剪切内容但最终得到了一个带有UIBezierPath的笔画(帧),这是我的代码

UIBezierPath *path2Path = [UIBezierPath bezierPath];
[path2Path moveToPoint:CGPointMake(206.745, 0)];
[path2Path addLineToPoint:CGPointMake(206.745, 97.613)];
[path2Path addLineToPoint:CGPointMake(0, 97.613)];
[path2Path addLineToPoint:CGPointMake(0, 0)];
[path2Path addLineToPoint:CGPointMake(87.28, 0)];
[path2Path addCurveToPoint:CGPointMake(103.808, 12.118) controlPoint1:CGPointMake(87.28, 0) controlPoint2:CGPointMake(86.555, 12.118)];
[path2Path addCurveToPoint:CGPointMake(119.466, 0) controlPoint1:CGPointMake(121.061, 12.118) controlPoint2:CGPointMake(119.466, 0)];
[path2Path addLineToPoint:CGPointMake(206.745, 0)];
[path2Path closePath];

[path2Path addClip];

CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame=MYVIEW.bounds;
pathLayer.path = path2Path.CGPath;

pathLayer.strokeColor = [[UIColor blackColor] CGColor];
pathLayer.fillColor = [[UIColor clearColor] CGColor];

pathLayer.fillRule=kCAFillRuleEvenOdd;
[MYVIEW.layer setMask:pathLayer];
[MYVIEW.layer setMasksToBounds:YES];

MYVIEW.backgroundColor=[UIColor greenColor];
Run Code Online (Sandbox Code Playgroud)

这段代码的结果只是一个绿色笔划线,边界是空的,就像这样 http://i.stack.imgur.com/aehdo.png

但是,我希望将界限设为绿色,并按中风进行修剪

Bli*_*nja 18

正如rob mayoff所说,你可以通过将视图的图层蒙版设置为CAShapeLayer来轻松完成.

UIBezierPath *myClippingPath = ...
CAShapeLayer *mask           = [CAShapeLayer layer];
mask.path                    = myClippingPath.CGPath;
myView.layer.mask            = mask;
Run Code Online (Sandbox Code Playgroud)

在斯威夫特

let myClippingPath = UIBezierPath( ... )
let mask           = CAShapeLayer()
mask.path          = myClippingPath.CGPath
layer.mask         = mask
Run Code Online (Sandbox Code Playgroud)


Fla*_*lar 5

谢谢你的回答.

如果有人几个小时都无法在SO上找到合适的答案,就像我刚刚做的那样,我已经在Swift 2.2中组装了一个工作要点,用于使用CGRect/UIBezierPath屏蔽/剪切UIView:

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

用法:

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

希望将来能节省一些时间:)