在iOS中,笔划掩盖了CALayer

时间:2013-08-21 12:13:49

标签: ios objective-c quartz-core

我正在尝试使用一个圆角和一个笔划/边框创建一个标签(或任何其他视图)。我可以使用以下代码实现前者:

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.label.bounds
                                      byRoundingCorners:UIRectCornerBottomRight
                                            cornerRadii:CGSizeMake(16.0f, 16.0f)];

CAShapeLayer *shape = [CAShapeLayer layer];
shape.frame = self.label.bounds;
shape.path = maskPath.CGPath;

self.label.layer.mask = shape;

哪个适用于圆角,但使用以下代码不会按照我想要的方式应用笔划。而是生成黑色(或backgroundColor self.label设置为边框。

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.label.bounds
                                      byRoundingCorners:UIRectCornerBottomRight
                                            cornerRadii:CGSizeMake(16.0f, 16.0f)];

CAShapeLayer *shape = [CAShapeLayer layer];
shape.frame = self.label.bounds;
shape.path = maskPath.CGPath;

// Add stroke
shape.borderWidth = 1.0f;
shape.borderColor = [UIColor whiteColor].CGColor;

self.label.backgroundColor = [UIColor blackColor];
self.label.layer.mask = shape;

关于如何在蒙版路径之后应用任意彩色笔划的任何建议?

2 个答案:

答案 0 :(得分:36)

你在形状图层的正确轨道上。但是你应该有两个不同的层。首先是第一个示例中的遮罩层,它掩盖了您的视图(切断了您不希望看到的区域)

然后您也添加了形状图层,但不是作为遮罩图层。另外,请确保不要使用borderWidth和borderColor,而是使用stroke。

//
// Create your mask first
//
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.label.bounds
                                      byRoundingCorners:UIRectCornerBottomRight
                                            cornerRadii:CGSizeMake(16.0f, 16.0f)];

CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.label.bounds;
maskLayer.path = maskPath.CGPath;
self.label.layer.mask = maskLayer;    

//
// And then create the outline layer
//
CAShapeLayer *shape = [CAShapeLayer layer];
shape.frame = self.label.bounds;
shape.path = maskPath.CGPath;
shape.lineWidth = 3.0f;
shape.strokeColor = [UIColor whiteColor].CGColor;
shape.fillColor = [UIColor clearColor].CGColor;
[self.label.layer addSublayer:shape];

请注意,笔触图层路径应位于蒙版路径的内部(小于)。否则,描边路径将被掩模层掩盖。我已经将lineWith设置为3,这使得你可以看到宽度的一半(1.5 px),另一半将在掩模之外。

答案 1 :(得分:0)

如果您继承CALayer,则可以使用所需的蒙版对其进行实例化,并覆盖layoutSubLayers以在该蒙版上包含所需的边框。

可以做几件事。在Ill下面,使用给定蒙版的path,并将其分配给class属性,用于在layoutSubLayers中构建新边框。有可能多次调用此方法,因此我还设置了一个布尔来跟踪它。 (也可以将边框指定为类属性,并且每次都删除/重新添加。现在,我使用bool检查。

斯威夫特3:

class CustomLayer: CALayer {

    private var path: CGPath?
    private var borderSet: Bool = false

    init(maskLayer: CAShapeLayer) {
        super.init()
        self.path = maskLayer.path
        self.frame = maskLayer.frame
        self.bounds = maskLayer.bounds
        self.mask = maskLayer
    }

    override func layoutSublayers() {

        let newBorder = CAShapeLayer()

        newBorder.lineWidth = 12
        newBorder.path = self.path
        newBorder.strokeColor = UIColor.black.cgColor
        newBorder.fillColor = nil


        if(!borderSet) {
            self.addSublayer(newBorder)
            self.borderSet = true
        }

    }

    required override init(layer: Any) {
        super.init(layer: layer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}