mercredi 25 mars 2015

Arrow anchor points not showing properly in swift

This is how anchor points now showing 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