Skip to content

Instantly share code, notes, and snippets.

@Coder-ACJHP
Created September 4, 2023 08:13
Show Gist options
  • Save Coder-ACJHP/5db11f2456b17a519cd0619dadf87314 to your computer and use it in GitHub Desktop.
Save Coder-ACJHP/5db11f2456b17a519cd0619dadf87314 to your computer and use it in GitHub Desktop.
Move image along UIBezierPath by percentage
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