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
CAShapeLayer mask view
提问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/clippingUIView和CGRect/组装了一个工作要点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 :)
希望它会在将来为某人节省一些时间:)

