在我的应用程序中,我需要一个箭头的轮廓,当用户通过某些活动进行时,它会充满颜色。要在我的视图中创建箭头形状,我已将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中我选择一个箭头图像,它会创建所需的形状:
此处视图具有灰色背景以用于演示目的。实际上我需要它是白色的,箭头显示为黑色轮廓:
所以基本上我需要一个围绕箭头面具的边框。实现这一结果的最佳方法是什么?
答案 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)
}
}