在箭头形状的面具周围画一个边框

时间:2017-11-06 12:12:31

标签: ios swift mask

在我的应用程序中,我需要一个箭头的轮廓,当用户通过某些活动进行时,它会充满颜色。要在我的视图中创建箭头形状,我已将UIView子类化为在Interface Builder中使用:

@IBDesignable
class MaskedView: UIView {

    var maskImageView = UIImageView()

    @IBInspectable var maskImage: UIImage? {
        didSet {
            maskImageView.image = maskImage
            maskImageView.contentMode = .scaleAspectFit
            maskImageView.frame = bounds
            mask = maskImageView
        }
    }

}

然后在IB中我选择一个箭头图像,它会创建所需的形状:

enter image description here

enter image description here

此处视图具有灰色背景以用于演示目的。实际上我需要它是白色的,箭头显示为黑色轮廓:

enter image description here

所以基本上我需要一个围绕箭头面具的边框。实现这一结果的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

yourView应该在clearColor。在CGPoint的帮助下,根据您的需要调整extension

let arrow = UIBezierPath.arrow(from: CGPoint(x: 50, y: 100), to: CGPoint(x: 200, y: 50),
                                       tailWidth: 10, headWidth: 25, headLength: 40)
let caLay = CAShapeLayer()
caLay.path = arrow.cgPath
yourView.layer.mask = caLay

let borderLayer = CAShapeLayer()
borderLayer.path = arrow.cgPath // Reuse the Bezier path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = UIColor.green.cgColor
borderLayer.lineWidth = 5
borderLayer.frame = greenview.bounds
yourView.layer.addSublayer(borderLayer)



extension UIBezierPath {

    class func arrow(from start: CGPoint, to end: CGPoint, tailWidth: CGFloat, headWidth: CGFloat, headLength: CGFloat) -> Self {
        let length = hypot(end.x - start.x, end.y - start.y)
        let tailLength = length - headLength

        func p(_ x: CGFloat, _ y: CGFloat) -> CGPoint { return CGPoint(x: x, y: y) }
        var points: [CGPoint] = [
            p(0, tailWidth / 2),
            p(tailLength, tailWidth / 2),
            p(tailLength, headWidth / 2),
            p(length, 0),
            p(tailLength, -headWidth / 2),
            p(tailLength, -tailWidth / 2),
            p(0, -tailWidth / 2)
        ]

        let cosine = (end.x - start.x) / length
        let sine = (end.y - start.y) / length
        var transform = CGAffineTransform(a: cosine, b: sine, c: -sine, d: cosine, tx: start.x, ty: start.y)
        let path = CGMutablePath()
        path.addLines(between: points, transform: transform)
        path.closeSubpath()
        return self.init(cgPath: path)
    }

}