This is the code which i am using to draw an arrow and add anchor points to it. But We can add arrow in different directions, because of that reason the anchor points got misplaced. Is there anyone knows how i can place these anchor points correctly at the starting point of the arrow and end point of the arrow.
//
// 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!)
{
}
}
Aucun commentaire:
Enregistrer un commentaire