I have a radial animation on programmatically created button which appear when the button is pressed.
If the button is pressed whilst the animation is already running, I want the animation to reset at the beginning and automatically play again.
In the "animationDidStop" function, I have code which applies when the animation does complete. The issue I have is when the button is pressed and an animation is already running. I can't remove the animation running and start a new one as it calls the "animationDidStop". I don't want this to be called yet.
My ideas was to adjust the animation value attached to the radial shape but this isn't working has planned . I know can access the animation values but which one would I change as "fromValue" doesn't show up. I also don't even know if this would actually work though or a better way. I been stuck for a while now.
var shapeLayerArray: [CustomShapeLayer] = []
func AutoUpRadial(button: CustomBtn, height: Int, value: Int){
let trackLayer = CustomShapeLayer()
let radius = height / 3
let circularPath = UIBezierPath(arcCenter: button.center, radius: CGFloat(radius), startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor.black.cgColor
trackLayer.opacity = 0.3
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.lineWidth = 5
trackLayer.strokeEnd = 0
mainScrollView.layer.addSublayer(trackLayer)
autoUpFillRadial(value: value, tmpBtn: button, shape: trackLayer)
shapeLayerArray.append(trackLayer)
}
@objc private func autoUpFillRadial(value: Int, tmpBtn: CustomBtn, shape: CustomShapeLayer){
let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.fromValue = 0
basicAnimation.toValue = 1
basicAnimation.duration = CFTimeInterval(value)
basicAnimation.fillMode = .forwards
basicAnimation.isRemovedOnCompletion = true
basicAnimation.setValue(tmpBtn.UUIDtag, forKey: "animationID")
basicAnimation.delegate = self
shape.add(basicAnimation, forKey: "basic")
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if let tag = anim.value(forKey: "animationID") as? UUID {
if let tmpButton: CustomBtn = tmpButtonPicked(uuid: tag) {
tmpButton.isSelected = false
actionInput(sender: tmpButton, act: "up")
}
}
}
Below is the button script
@IBAction func clipButton(sender: CustomBtn){
currentSelectedMarkerUUID = sender.UUIDtag
if let marker = markUpPlist.arrayObjects.filter({$0.UUIDpic == currentSelectedMarkerUUID}).first {
if recording {
if sender.isSelected {
if !shapeLayerArray.isEmpty {
for shape in shapeLayerArray {
if shape.uuidTag == marker.UUIDpic {
print(shape.animation(forKey: "basic"))
// The line aboves shows the animation data
sender.isSelected = true
} else {
sender.isSelected = false
endClip(sender: sender)
}
}
} else if shapeLayerArray.isEmpty {
sender.isSelected = false
endClip(sender: sender)
}
} else if !sender.isSelected {
sender.isSelected = true
startClip(sender: sender)
if marker.timeAutoUp > 0 {
if !shapeLayerArray.isEmpty {
for shape in shapeLayerArray {
if shape.uuidTag == marker.UUIDpic {
//DO SOMETHING
} else {
self.AutoUpRadial(button: sender, height: marker.height, value: marker.timeAutoUp)
}
}
} else if shapeLayerArray.isEmpty {
self.AutoUpRadial(button: sender, height: marker.height, value: marker.timeAutoUp)
}
}
} else {
sender.isSelected = false
}
}
}
}
class CustomShapeLayer: CAShapeLayer {
var uuidTag: UUID?
}
So to recap, I want to be able to reset the animation if the animation is already playing when the button is pressed but without calling the animationDidStop function.
I tried to remove as much stuff irrelevant to the code to condense it as much as I could. Hopefully it makes sense. Thanks for any advice
After hours stuck on it I came up with this. I added a reset boolean in my custom CAshapelayer. The reset bool gets called when the button is pressed and the animation is already running.
class CustomShapeLayer: CAShapeLayer {
var uuidTag: UUID?
vart reset = false
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if let tag = anim.value(forKey: "animationID") as? UUID {
if let tmpButton: CustomBtn = tmpButtonPicked(uuid: tag) {
if !shapeLayerArray.isEmpty {
for shape in shapeLayerArray {
if shape.uuidTag == tag{
if shape.reset {
shape.reset = false
} else {
tmpButton.isSelected = false
actionInput(sender: tmpButton, act: "up")
}
} else {
tmpButton.isSelected = false
actionInput(sender: tmpButton, act: "up")
}
}
} else if shapeLayerArray.isEmpty {
tmpButton.isSelected = false
actionInput(sender: tmpButton, act: "up")
}
}
}
}