Created
September 4, 2023 08:13
-
-
Save Coder-ACJHP/5db11f2456b17a519cd0619dadf87314 to your computer and use it in GitHub Desktop.
Move image along UIBezierPath by percentage
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
fileprivate var circleIcon: UIImageView! | |
fileprivate var circlePathaAnimation: CAKeyframeAnimation! | |
// Drawing func that takes x position as an argument | |
// Call this funtion inside 'drawRect' or 'onTouchMoves' | |
fileprivate func drawHighlightCircleFromLeftPosition(_ posiX: CGFloat) { | |
// If imageView and animation already created and existing change percentage | |
if let circleIcon = self.circleIcon, | |
let animation = circlePathaAnimation { | |
// Calculate percentage (value will be between 0.0 and 1.0) | |
let percentage = posiX / drawingWidth | |
circleIcon.layer.timeOffset = animation.beginTime + percentage | |
} else { | |
let imageView = UIImageView(image: UIImage(named: "icon.plan.selected.radio")) | |
imageView.contentMode = .scaleAspectFit | |
imageView.frame = CGRect(x: 0, y: 0, width: 15, height: 15) | |
self.circleIcon = imageView | |
self.addSubview(imageView) | |
circlePathaAnimation = CAKeyframeAnimation(keyPath: "position") | |
circlePathaAnimation.path = createHighlightCirclePath().cgPath | |
circlePathaAnimation.calculationMode = .paced | |
circlePathaAnimation.fillMode = .forwards | |
circlePathaAnimation.duration = 1 | |
circlePathaAnimation.isRemovedOnCompletion = false | |
circlePathaAnimation.beginTime = CACurrentMediaTime() | |
// Immediately pause the animation | |
imageView.layer.speed = 0 | |
imageView.layer.add(circlePathaAnimation, forKey: "path") | |
} | |
} | |
// Create your animation path | |
fileprivate func createHighlightCirclePath() -> UIBezierPath { | |
let path = UIBezierPath() | |
for (_, series) in self.series.enumerated() { | |
// Separate each line in multiple segments over and below the x axis | |
let scaledX = scaleValuesOnXAxis(series.data.map({ $0.x })) | |
let scaledY = scaleValuesOnYAxis(series.data.map({ $0.y })) | |
for index in 0 ..< scaledX.count { | |
let posiX = scaledX[index] | |
let posiY = scaledY[index] | |
if index == .zero { | |
path.move(to: CGPoint(x: posiX, y: posiY)) | |
} else { | |
path.addLine(to: CGPoint(x: posiX, y: posiY)) | |
} | |
} | |
} | |
return path | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment