Ios 在箭头形状的遮罩周围绘制边框

Ios 在箭头形状的遮罩周围绘制边框,ios,swift,mask,Ios,Swift,Mask,在我的应用程序中,我需要一个箭头的轮廓,当用户进行某些活动时,它会被颜色填充。要在我的视图中创建箭头形状,我将UIView子类化,以便在Interface Builder中使用: @IBDesignable class MaskedView: UIView { var maskImageView = UIImageView() @IBInspectable var maskImage: UIImage? { didSet { maskI

在我的应用程序中,我需要一个箭头的轮廓,当用户进行某些活动时,它会被颜色填充。要在我的视图中创建箭头形状,我将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中,我选择一个箭头图像,它创建了所需的形状:

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


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

您的视图应位于
clearColor
中。在
分机的帮助下,根据您的需要调整
CGPoint

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)
    }

}

使用UIBezierPath创建路径对象。如果我的答案有效,请告诉我?我想到了,但实际上希望避免手动绘制,因为它容易出错,并且很难为自动布局进行自定义。我想知道斯威夫特是否有办法从图像形状创建UIBezierPath。在创建遮罩时,它确实可以识别形状,所以为什么不在它周围画一条具有给定线宽的路径,我想)此外,在未来的版本中,箭头形状很有可能会改变。它可能变得更复杂,例如在底部模仿羽毛。这需要20-40分来管理。