ios CAShapeLayer 带边框和填充颜色和四舍五入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12756928/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:37:22  来源:igfitidea点击:

CAShapeLayer with border and fill color and rounding

iphoneiosipadcore-animation

提问by jjxtra

How do I use CAShapeLayer to draw a line that has both a border color, border width and fill color?

如何使用 CAShapeLayer 绘制具有边框颜色、边框宽度和填充颜色的线条?

Here's what I've tried, but it's only ever blue...

这是我尝试过的,但它只是蓝色......

self.lineShape.strokeColor = [UIColor blueColor].CGColor;
self.lineShape.fillColor = [UIColor greenColor].CGColor;
self.lineShape.lineWidth = 100;
self.lineShape.lineCap = kCALineCapRound;
self.lineShape.lineJoin = kCALineJoinRound;
UIBezierPath* path = [UIBezierPath bezierPath];
[path moveToPoint:self.lineStart];
[path addLineToPoint:self.lineEnd];
self.lineShape.path = path.CGPath;

回答by jjxtra

    self.lineShapeBorder = [[CAShapeLayer alloc] init];
    self.lineShapeBorder.zPosition = 0.0f;
    self.lineShapeBorder.strokeColor = [UIColor blueColor].CGColor;
    self.lineShapeBorder.lineWidth = 25;
    self.lineShapeBorder.lineCap = kCALineCapRound;
    self.lineShapeBorder.lineJoin = kCALineJoinRound;

    self.lineShapeFill = [[CAShapeLayer alloc] init];
    [self.lineShapeBorder addSublayer:self.lineShapeFill];
    self.lineShapeFill.zPosition = 0.0f;
    self.lineShapeFill.strokeColor = [UIColor greenColor].CGColor;
    self.lineShapeFill.lineWidth = 20.0f;
    self.lineShapeFill.lineCap = kCALineCapRound;
    self.lineShapeFill.lineJoin = kCALineJoinRound;

// ...

    UIBezierPath* path = [UIBezierPath bezierPath];
    [path moveToPoint:self.lineStart];
    [path addLineToPoint:self.lineEnd];
    self.lineShapeBorder.path = self.lineShapeFill.path = path.CGPath;

回答by rob mayoff

If you set the layer's fillColorproperty to something other than nilor transparent, the layer will fill its path.

如果您将图层的fillColor属性设置为非nil透明或透明,图层将填充其路径。

If you set the layer's lineWidthto a number larger than zero and you set its strokeColorto something other than nilor transparent, the layer will stroke its path.

如果将图层设置为lineWidth大于零的数字,并将其strokeColor设置为非nil透明或透明,则图层将描边其路径。

If you set all of those properties, the layer will fill andstroke its path. It draws the stroke after the fill.

如果您设置了所有这些属性,图层将填充描边其路径。它在填充后绘制笔划。

The layer's path must actually enclose some area in order for it to fill anything. In your post, you set the path like this:

图层的路径实际上必须包含一些区域才能填充任何内容。在您的帖子中,您设置的路径如下:

UIBezierPath* path = [UIBezierPath bezierPath];
[path moveToPoint:self.lineStart];
[path addLineToPoint:self.lineEnd];
self.lineShape.path = path.CGPath;

That path contains a single line segment. It doesn't enclose any area, so the layer has nothing to fill.

该路径包含单个线段。它不包含任何区域,因此该图层没有任何可填充的内容。

回答by AechoLiu

In Swift 3. an extension method of UIView.

在 Swift 3. 中的一个扩展方法UIView

// Usage:
self.btnGroup.roundCorner([.topRight, .bottomRight], radius: 4.0, borderColor: UIColor.red, borderWidth: 1.0)

// Apply round corner and border. An extension method of UIView.
public func roundCorner(_ corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
    let path = UIBezierPath.init(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))

    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask

    let borderPath = UIBezierPath.init(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let borderLayer = CAShapeLayer()
    borderLayer.path = borderPath.cgPath
    borderLayer.lineWidth = borderWidth
    borderLayer.strokeColor = borderColor.cgColor
    borderLayer.fillColor = UIColor.clear.cgColor
    borderLayer.frame = self.bounds
    self.layer.addSublayer(borderLayer)
}