-
-
Save mwermuth/07825df27ea28f5fc89a to your computer and use it in GitHub Desktop.
extension UIBezierPath { | |
class func getAxisAlignedArrowPoints(inout points: Array<CGPoint>, forLength: CGFloat, tailWidth: CGFloat, headWidth: CGFloat, headLength: CGFloat ) { | |
let tailLength = forLength - headLength | |
points.append(CGPointMake(0, tailWidth/2)) | |
points.append(CGPointMake(tailLength, tailWidth/2)) | |
points.append(CGPointMake(tailLength, headWidth/2)) | |
points.append(CGPointMake(forLength, 0)) | |
points.append(CGPointMake(tailLength, -headWidth/2)) | |
points.append(CGPointMake(tailLength, -tailWidth/2)) | |
points.append(CGPointMake(0, -tailWidth/2)) | |
} | |
class func transformForStartPoint(startPoint: CGPoint, endPoint: CGPoint, length: CGFloat) -> CGAffineTransform{ | |
let cosine: CGFloat = (endPoint.x - startPoint.x)/length | |
let sine: CGFloat = (endPoint.y - startPoint.y)/length | |
return CGAffineTransformMake(cosine, sine, -sine, cosine, startPoint.x, startPoint.y) | |
} | |
class func bezierPathWithArrowFromPoint(startPoint:CGPoint, endPoint: CGPoint, tailWidth: CGFloat, headWidth: CGFloat, headLength: CGFloat) -> UIBezierPath { | |
let xdiff: Float = Float(endPoint.x) - Float(startPoint.x) | |
let ydiff: Float = Float(endPoint.y) - Float(startPoint.y) | |
let length = hypotf(xdiff, ydiff) | |
var points = [CGPoint]() | |
self.getAxisAlignedArrowPoints(&points, forLength: CGFloat(length), tailWidth: tailWidth, headWidth: headWidth, headLength: headLength) | |
var transform: CGAffineTransform = self.transformForStartPoint(startPoint, endPoint: endPoint, length: CGFloat(length)) | |
var cgPath: CGMutablePathRef = CGPathCreateMutable() | |
CGPathAddLines(cgPath, &transform, points, 7) | |
CGPathCloseSubpath(cgPath) | |
var uiPath: UIBezierPath = UIBezierPath(CGPath: cgPath) | |
return uiPath | |
} | |
} |
how to draw curved arrow ???
let arrowPath = UIBezier. bezierPathWithArrowFromPoint(CGPointMake(0,0), CGPointMake(0,20), 4, 8, 6)
How overlay this arrowPath on UIImageView() ?
Updated for Swift 5:
`extension UIBezierPath {
class func getAxisAlignedArrowPoints(points: inout [CGPoint], forLength: CGFloat, tailWidth: CGFloat, headWidth: CGFloat, headLength: CGFloat) {
let tailLength = forLength - headLength
points.append(CGPointMake(0, tailWidth / 2))
points.append(CGPointMake(tailLength, tailWidth / 2))
points.append(CGPointMake(tailLength, headWidth / 2))
points.append(CGPointMake(forLength, 0))
points.append(CGPointMake(tailLength, -headWidth / 2))
points.append(CGPointMake(tailLength, -tailWidth / 2))
points.append(CGPointMake(0, -tailWidth / 2))
}
class func transformForStartPoint(startPoint: CGPoint, endPoint: CGPoint, length: CGFloat) -> CGAffineTransform {
let cosine: CGFloat = (endPoint.x - startPoint.x) / length
let sine: CGFloat = (endPoint.y - startPoint.y) / length
return CGAffineTransformMake(cosine, sine, -sine, cosine, startPoint.x, startPoint.y)
}
class func bezierPathWithArrowFromPoint(startPoint: CGPoint,
endPoint: CGPoint,
tailWidth: CGFloat,
headWidth: CGFloat,
headLength: CGFloat) -> UIBezierPath
{
let xdiff = Float(endPoint.x) - Float(startPoint.x)
let ydiff = Float(endPoint.y) - Float(startPoint.y)
let length = hypotf(xdiff, ydiff)
var points = [CGPoint]()
getAxisAlignedArrowPoints(points: &points, forLength: CGFloat(length), tailWidth: tailWidth, headWidth: headWidth, headLength: headLength)
let transform: CGAffineTransform = transformForStartPoint(startPoint: startPoint, endPoint: endPoint, length: CGFloat(length))
let cgPath = CGMutablePath()
cgPath.addLines(between: points, transform: transform)
cgPath.closeSubpath()
let uiPath = UIBezierPath(cgPath: cgPath)
return uiPath
}
}`
How to use it between views?