【问题标题】:Stroke masked CALayer in iOSiOS中的中风蒙版CALayer
【发布时间】:2013-08-21 12:13:48
【问题描述】:

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

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;

这对圆角很有效,但使用下面的代码并不能按照我想要的方式应用笔画。而是产生黑色(或任何 self.label 的 backgroundColor 设置为)方形边框。

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;

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

【问题讨论】:

    标签: ios objective-c quartz-core


    【解决方案1】:

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

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

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

    【讨论】:

    • 这种工作,但现在标签的文本已被shape 层覆盖:(
    • 好的,我已经设法通过将掩码应用于UIView 并将UILabel 添加为子视图来使其工作。非常感谢:)
    • StrokeLayer 覆盖了标签,所以我添加了这个来修复它shape.fillColor = [UIColor clearColor].CGColor
    【解决方案2】:

    如果您将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-07-03
      • 1970-01-01
      • 2012-09-15
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2017-08-25
      • 2014-03-27
      • 2013-03-26
      相关资源
      最近更新 更多