Как создать закругленные углы с помощью CAShapeLayer

есть ли способ добавить закругленные углы в CAShapeLayer? В моем случае мне нужен слой формы для создания пунктирной границы через lineDashPattern.

Rounded corners with dashed line - incorrect

^ обратите внимание, что пунктирная линия не закруглена

2 ответов


ответ прост. Создайте путь Безье со скругленными углами.

self.clipsToBounds = YES; 
self.layer.cornerRadius = 10.0;

self.border = [CAShapeLayer layer];
self.border.fillColor = nil;
self.border.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:10.0];
self.border.frame = self.bounds;

self.border.strokeColor = [UIColor purpleColor].CGColor;
self.border.lineWidth = borderWidth * 2; // double desired width as half will be clipped
self.border.lineDashPattern = @[@15];

[self.layer addSublayer:self.border];

Rounded corners with dashed line - correct


в swift 4 я создал категорию UIView (UIView+Borders) со следующей функцией:

func borderDash(withRadius cornerRadius: Float, borderWidth: Float, borderColor: UIColor, dashSize: Int) {
    let currentFrame = self.bounds
    let shapeLayer = CAShapeLayer()
    let path = CGMutablePath()
    let radius = CGFloat(cornerRadius)

    // Points - Eight points that define the round border. Each border is defined by two points.
    let topLeftPoint = CGPoint(x: radius, y: 0)
    let topRightPoint = CGPoint(x: currentFrame.size.width - radius, y: 0)
    let middleRightTopPoint = CGPoint(x: currentFrame.size.width, y: radius)
    let middleRightBottomPoint = CGPoint(x: currentFrame.size.width, y: currentFrame.size.height - radius)
    let bottomRightPoint = CGPoint(x: currentFrame.size.width - radius, y: currentFrame.size.height)
    let bottomLeftPoint = CGPoint(x: radius, y: currentFrame.size.height)
    let middleLeftBottomPoint = CGPoint(x: 0, y: currentFrame.size.height - radius)
    let middleLeftTopPoint = CGPoint(x: 0, y: radius)

    // Points - Four points that are the center of the corners borders.
    let cornerTopRightCenter = CGPoint(x: currentFrame.size.width - radius, y: radius)
    let cornerBottomRightCenter = CGPoint(x: currentFrame.size.width - radius, y: currentFrame.size.height - radius)
    let cornerBottomLeftCenter = CGPoint(x: radius, y: currentFrame.size.height - radius)
    let cornerTopLeftCenter = CGPoint(x: radius, y: radius)

    // Angles - The corner radius angles.
    let topRightStartAngle = CGFloat(Double.pi * 3 / 2)
    let topRightEndAngle = CGFloat(0)
    let bottomRightStartAngle = CGFloat(0)
    let bottmRightEndAngle = CGFloat(Double.pi / 2)
    let bottomLeftStartAngle = CGFloat(Double.pi / 2)
    let bottomLeftEndAngle = CGFloat(Double.pi)
    let topLeftStartAngle = CGFloat(Double.pi)
    let topLeftEndAngle = CGFloat(Double.pi * 3 / 2)

    // Drawing a border around a view.
    path.move(to: topLeftPoint)
    path.addLine(to: topRightPoint)
    path.addArc(center: cornerTopRightCenter,
                radius: radius,
                startAngle: topRightStartAngle,
                endAngle: topRightEndAngle,
                clockwise: false)
    path.addLine(to: middleRightBottomPoint)
    path.addArc(center: cornerBottomRightCenter,
                radius: radius,
                startAngle: bottomRightStartAngle,
                endAngle: bottmRightEndAngle,
                clockwise: false)
    path.addLine(to: bottomLeftPoint)
    path.addArc(center: cornerBottomLeftCenter,
                radius: radius,
                startAngle: bottomLeftStartAngle,
                endAngle: bottomLeftEndAngle,
                clockwise: false)
    path.addLine(to: middleLeftTopPoint)
    path.addArc(center: cornerTopLeftCenter,
                radius: radius,
                startAngle: topLeftStartAngle,
                endAngle: topLeftEndAngle,
                clockwise: false)

    // Path is set as the shapeLayer object's path.
    shapeLayer.path = path;
    shapeLayer.backgroundColor = UIColor.clear.cgColor
    shapeLayer.frame = currentFrame
    shapeLayer.masksToBounds = false
    shapeLayer.setValue(0, forKey: "isCircle")
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = borderColor.cgColor
    shapeLayer.lineWidth = CGFloat(borderWidth)
    shapeLayer.lineDashPattern = [NSNumber(value: dashSize), NSNumber(value: dashSize)]
    shapeLayer.lineCap = kCALineCapRound

    self.layer.addSublayer(shapeLayer)
    self.layer.cornerRadius = radius;
}