Created
February 20, 2019 20:37
-
-
Save policante/8fef90f9304e44a97b5df0c57f6ffa07 to your computer and use it in GitHub Desktop.
Classe para desenhar linha animada entre 2 pontos
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LineDrawerView: UIView { | |
convenience init() { | |
self.init(frame: .zero) | |
} | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = .white | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError() | |
} | |
func drawLayer(_ startPoint: CGPoint, endPoint: CGPoint, animated: Bool, delegate: CAAnimationDelegate? = nil){ | |
self.layer.sublayers?.forEach({ (la) in | |
la.removeAllAnimations() | |
la.removeFromSuperlayer() | |
}) | |
let path = UIBezierPath() | |
path.move(to: startPoint) | |
let centerY = ((startPoint.y + endPoint.y) / 2) | |
path.addCurve(to: endPoint, controlPoint1: CGPoint(x: startPoint.x, y: centerY * 1.3), controlPoint2: CGPoint(x: endPoint.x, y: centerY * 0.7)) | |
let layer = CAShapeLayer() | |
layer.path = path.cgPath | |
layer.strokeEnd = animated ? 0 : 1 | |
layer.lineWidth = 3 | |
layer.lineDashPattern = [32, 16] // first is the length of dash, second is length of the gap. | |
layer.strokeColor = UIColor.black.cgColor | |
layer.fillColor = UIColor.clear.cgColor | |
self.layer.addSublayer(layer) | |
let pathArrow = UIBezierPath() | |
pathArrow.addArrow(start: CGPoint(x: endPoint.x, y: centerY), end: endPoint, pointerLineLength: 30, arrowAngle: CGFloat(Double.pi / 4)) | |
let layerArrow = CAShapeLayer() | |
layerArrow.path = pathArrow.cgPath | |
layerArrow.strokeEnd = animated ? 0 : 1 | |
layerArrow.lineWidth = 3 | |
layerArrow.strokeColor = UIColor.black.cgColor | |
layerArrow.fillColor = UIColor.clear.cgColor | |
self.layer.addSublayer(layerArrow) | |
if animated { | |
let animation = CABasicAnimation(keyPath: "strokeEnd") | |
animation.toValue = 1 | |
animation.duration = 2 | |
animation.autoreverses = false | |
animation.repeatCount = 0 | |
animation.fillMode = .forwards | |
animation.isRemovedOnCompletion = false | |
layer.add(animation, forKey: "line") | |
let animationArrow = CABasicAnimation(keyPath: "strokeEnd") | |
animationArrow.toValue = 1 | |
animationArrow.beginTime = CACurrentMediaTime() + animation.duration + 0.1 | |
animationArrow.duration = 0.5 | |
animationArrow.autoreverses = false | |
animationArrow.repeatCount = 0 | |
animationArrow.fillMode = .forwards | |
animationArrow.isRemovedOnCompletion = false | |
animationArrow.delegate = delegate | |
layerArrow.add(animationArrow, forKey: "arrow") | |
} | |
} | |
} | |
extension UIBezierPath { | |
func addArrow(start: CGPoint, end: CGPoint, pointerLineLength: CGFloat, arrowAngle: CGFloat) { | |
let startEndAngle = atan((end.y - start.y) / (end.x - start.x)) + ((end.x - start.x) < 0 ? CGFloat(Double.pi) : 0) | |
let arrowLine1 = CGPoint(x: end.x + pointerLineLength * cos(CGFloat(Double.pi) - startEndAngle + arrowAngle), y: end.y - pointerLineLength * sin(CGFloat(Double.pi) - startEndAngle + arrowAngle)) | |
let arrowLine2 = CGPoint(x: end.x + pointerLineLength * cos(CGFloat(Double.pi) - startEndAngle - arrowAngle), y: end.y - pointerLineLength * sin(CGFloat(Double.pi) - startEndAngle - arrowAngle)) | |
self.move(to: end) | |
self.addLine(to: arrowLine1) | |
self.move(to: end) | |
self.addLine(to: arrowLine2) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment