这是我用来绘制箭头并为其添加锚点的代码。但是我们可以在不同方向添加箭头,因为这个原因锚点错位。有没有人知道如何在箭头的起点和箭头的终点正确放置这些锚点。
//
// AnnotationArrow.swift
//
//
// Created by Alvin Varghese on 10/Mar/15.
// Copyright (c) 2015![enter image description here][2]. All rights reserved.
//
import UIKit
protocol _Annotation_ARROW_PROTOCOL
{
func valuesFromArrowSubClass(instance : AnnotationArrow)
}
class AnnotationArrow: UIView
{
//MARK: Global Variables
var startingPoint : CGPoint = CGPoint()
var endingPoint : CGPoint = CGPoint()
var arrowLength : CGFloat = CGFloat()
var arrowPath : UIBezierPath = UIBezierPath()
var selectedInBox_Activated_Anchor_Points = false
var delegate : _Annotation_ARROW_PROTOCOL!
//MARK: For resizing
var kUserResizableViewDefaultMinWidth = 40.0
var kUserResizableViewDefaultMinHeight = 40.0
var kUserResizableViewInteractiveBorderSize = 10.0
//MARK: initFrame
override init(frame: CGRect)
{
super.init(frame: frame)
}
//MARK: initCoder
required init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
func passingValues(startingPointValue : CGPoint, endingPointValue : CGPoint)
{
self.startingPoint = startingPointValue
self.endingPoint = endingPointValue
var xDistance : CGFloat = self.endingPoint.x - self.startingPoint.x
var yDistance : CGFloat = self.endingPoint.y - self.startingPoint.y
self.arrowLength = sqrt((xDistance * xDistance) + (yDistance * yDistance))
}
//MARK: drawRect
override func drawRect(rect: CGRect)
{
var tailWidth : CGFloat = max(4.0, self.arrowLength * 0.07)
var headLength : CGFloat = max(self.arrowLength / 3.0, 10.0)
var headWidth : CGFloat = headLength * 0.9
var strokeWidth : CGFloat = max(1.0, tailWidth * 0.25)
self.layer.shadowRadius = max(4.0, tailWidth)
self.arrowPath = self.bezierPathWithArrowFromPoint(self.startingPoint, endPoint: self.endingPoint, tailWidth: tailWidth, headWidth: headWidth, headLength: headLength)
self.arrowPath.fill()
self.arrowPath.stroke()
self.arrowPath.lineWidth = strokeWidth
self.layer.shadowPath = self.arrowPath.CGPath
if self.selectedInBox_Activated_Anchor_Points
{
// Starting the code for - ResizableView anchor points
var color : UIColor = UIColor.greenColor()
var context : CGContextRef = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
// 1 - Drawing the bounding box
CGContextSetFillColorWithColor(context, color.CGColor)
CGContextSetStrokeColorWithColor(context, color.CGColor)
CGContextMoveToPoint(context, self.startingPoint.x, self.startingPoint.y)
CGContextAddLineToPoint(context, self.endingPoint.x, self.endingPoint.y )
CGContextSetLineWidth(context, 2.0)
CGContextStrokePath(context)
CGContextSetStrokeColorWithColor(context, color.CGColor)
// 2 - Calculate the bounding boxes for each of the anchor points.
var startingSectionRect : CGRect = CGRectMake(self.startingPoint.x, self.startingPoint.y, 20.0, 20.0)
var endingSectionRect : CGRect = CGRectMake(self.endingPoint.x, self.endingPoint.y, 20.0, 20.0)
// 3 - Create the gradient to paint the anchor points.
var colors : [CGFloat] = [1.0, 1.0]
var baseSpace : CGColorSpaceRef = CGColorSpaceCreateDeviceRGB()
var gradient : CGGradientRef = CGGradientCreateWithColorComponents(baseSpace, colors, nil, 2)
// 4 - Set up the stroke for drawing the border of each of the anchor points.
CGContextSetLineWidth(context, 2.0)
CGContextSetShadow(context, CGSizeMake(0.5, 0.5), 1)
CGContextSetStrokeColorWithColor(context, color.CGColor)
// 5 - Fill each anchor point using the gradient, then stroke the border.
var allPoints : [CGRect] = [ startingSectionRect, endingSectionRect]
for index in 0..<2
{
var currentPoint : CGRect = allPoints[index]
CGContextSaveGState(context)
CGContextAddEllipseInRect(context, currentPoint)
CGContextClip(context)
var startPoint : CGPoint = CGPointMake(CGRectGetMidX(currentPoint), CGRectGetMinY(currentPoint))
var endPoint : CGPoint = CGPointMake(CGRectGetMidX(currentPoint), CGRectGetMaxY(currentPoint))
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0)
CGContextRestoreGState(context)
UIColor.greenColor().setFill()
// CGContextStrokeEllipseInRect(context, CGRectInset(currentPoint, 1, 1))
CGContextFillEllipseInRect(context, currentPoint)
}
// Restoring state to most recently saved state
CGContextRestoreGState(context)
}
}
//MARK: hitTest
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView?
{
if self.arrowPath.containsPoint(point)
{
self.selectedInBox_Activated_Anchor_Points = true
self.setNeedsDisplay()
self.delegate.valuesFromArrowSubClass(self)
return self
}
var boundingBox : CGRect = self.arrowPath.bounds
if ((boundingBox.size.width < 80 || boundingBox.size.height < 80) && CGRectContainsPoint(boundingBox, point))
{
self.selectedInBox_Activated_Anchor_Points = true
self.setNeedsDisplay()
self.delegate.valuesFromArrowSubClass(self)
return self
}
self.selectedInBox_Activated_Anchor_Points = false
self.setNeedsDisplay()
return nil
}
//MARK: Creating Path
func bezierPathWithArrowFromPoint(startingPoint : CGPoint, endPoint : CGPoint, tailWidth : CGFloat, headWidth : CGFloat, headLength : CGFloat) -> UIBezierPath
{
var length = hypotf( Float(endPoint.x) - Float(startingPoint.x) , Float(endPoint.y) - Float(startingPoint.y))
var tailLength : CGFloat = CGFloat(length) - headLength
var points = [CGPointMake(0, tailWidth / 2), CGPointMake(tailLength, tailWidth / 2), CGPointMake(tailLength, headWidth / 2), CGPointMake(CGFloat(length), 0), CGPointMake(tailLength, (-headWidth) / 2), CGPointMake(tailLength, (-tailWidth) / 2 ), CGPointMake(0, (-tailWidth) / 2)]
var cosine : CGFloat = (endPoint.x - startingPoint.x) / CGFloat(length)
var sine : CGFloat = (endPoint.y - startingPoint.y) / CGFloat(length)
var transform : CGAffineTransform = CGAffineTransform(a: cosine, b: sine, c: -sine, d: cosine, tx: startingPoint.x, ty: startingPoint.y)
var cgPath : CGMutablePathRef = CGPathCreateMutable()
CGPathAddLines(cgPath, &transform, points, (UInt)(points.count))
CGPathCloseSubpath(cgPath)
var bezierPath : UIBezierPath = UIBezierPath(CGPath: cgPath)
bezierPath.lineCapStyle = kCGLineCapRound
bezierPath.lineJoinStyle = kCGLineJoinRound
return bezierPath
}
//MARK: UITouch Methods
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
{
var touch : UITouch = touches.anyObject() as UITouch
}
override func touchesMoved(touches: NSSet, withEvent event: UIEvent)
{
var touch : UITouch = touches.allObjects.last as UITouch
var point = touch.locationInView(self.superview)
}
override func touchesEnded(touches: NSSet, withEvent event: UIEvent)
{
}
override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!)
{
}
}
答案 0 :(得分:2)
在绘制时,您正在考虑将您的点作为矩形:
var startingSectionRect : CGRect = CGRectMake(self.startingPoint.x, self.startingPoint.y, 20.0, 20.0)
然后用椭圆(圆圈)填充此矩形。这显然是错的,因为你感兴趣的一点是留在左上角,而你想要它在中心:
let pointSize = 20.0
var startingSectionRect = CGRectMake(self.startingPoint.x - pointSize / 2.0, self.startingPoint.y - pointSize / 2.0, pointSize, pointSize)