12

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

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;

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

4

2 回答 2

36

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

然后你也添加形状层,但不是作为蒙版层。另外,请确保不要使用边框宽度和边框颜色,而是使用描边。

//
// 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),而另一半将在遮罩之外。

于 2013-08-21T12:36:47.370 回答
0

如果您子类CALayer化,您可以使用您想要的掩码对其进行实例化,并且还可以覆盖layoutSubLayers以在该掩码上包含您想要的边框。

可以通过几种方式做到这一点。下面我将通过使用path给定掩码的 来做到这一点,并将其分配给类属性以用于在 中构造新边框layoutSubLayers。这个方法有可能被多次调用,所以我还设置了一个布尔值来跟踪它。(也可以将边框指定为类属性,并每次删除/重新添加。现在,我使用布尔检查。

斯威夫特 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")
    }
}
于 2017-08-23T21:58:15.063 回答