0

I am building an app that will show an animation when a certain function is running and remove it once the next function runs. However I need it to restart when it loops back.

I have been able to remove it from the view with

isHidden = true

But if I rely on this to bring it back it layers a second animation over the first when it runs again and I unhide it.

I was also able to use .removeFromSuperView()

to make it disappear but I can't figure out how to bring it back after that.

Here is the relevant code:

class ViewController: UIViewController {
// some code
let dots = UIImageView()

     override func viewDidLoad() {
        super.viewDidLoad()

// some code

dots.translatesAutoresizingMaskIntoConstraints = false
        dots.backgroundColor = .red
        dots.center = self.view.center
        

 view.addSubview(dots)

// Some Auto Layout code
}

func showAnimatingDotsInImageView(_ isOn: Bool) {
    let lay = CAReplicatorLayer()
    if isOn == true {
        lay.frame = CGRect(x: -55, y: 0, width: 30, height: 14) //yPos == 12
        let circle = CALayer()
        circle.frame = CGRect(x: 10, y: 10, width: 10, height: 10)
        circle.cornerRadius = circle.frame.width / 2
        circle.backgroundColor = rocketDark.cgColor//lightGray.cgColor //UIColor.black.cgColor
        lay.addSublayer(circle)
        lay.instanceCount = 5
        lay.instanceTransform = CATransform3DMakeTranslation(20, 0, 0)
        let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
        anim.fromValue = 0.0
        anim.toValue = 1.0
        anim.duration = 2
        anim.repeatCount = .infinity
        circle.add(anim, forKey: "animation")
        lay.instanceDelay = anim.duration / Double(lay.instanceCount)
        dots.layer.addSublayer(lay)
    } else if isOn == false {
        //lay.removeFromSuperlayer()
        //lay.removeAllAnimations()
        dots.removeFromSuperview()
        //dots.stopAnimating()
    }
}

As you can probably tell I was attempting to hack together a way to write howAnimatingDotsInImageView(false) to remove it and howAnimatingDotsInImageView(true) to restart it.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
pawCheese
  • 13
  • 1
  • 1
    You remove `dots` from the interface but then you never add it to the interface again. So obviously you can't animate in this view because there is no view. – matt Oct 26 '21 at 13:01

1 Answers1

-1

I didn't compile this code, but I think using this approach you can remove your animation

class ViewController: UIViewController {
// some code
let dots = UIImageView()
let circleLayer: CAlayer? // Save circle layer property

     override func viewDidLoad() {
        super.viewDidLoad()

// some code

dots.translatesAutoresizingMaskIntoConstraints = false
        dots.backgroundColor = .red
        dots.center = self.view.center
        

 view.addSubview(dots)

// Some Auto Layout code
}

func showAnimatingDotsInImageView(_ isOn: Bool) {
    let lay = CAReplicatorLayer()
    if isOn == true {
        lay.frame = CGRect(x: -55, y: 0, width: 30, height: 14) //yPos == 12
        circleLayer = CALayer()
        circleLayer?.frame = CGRect(x: 10, y: 10, width: 10, height: 10)
        circleLayer?.cornerRadius = circle?.frame.width / 2 ?? .zero
        circleLayer?.backgroundColor = rocketDark.cgColor//lightGray.cgColor //UIColor.black.cgColor
        circleLayer.map { lay.addSublayer($0) }
        lay.instanceCount = 5
        lay.instanceTransform = CATransform3DMakeTranslation(20, 0, 0)
        let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
        anim.fromValue = 0.0
        anim.toValue = 1.0
        anim.duration = 2
        anim.repeatCount = .infinity
        circleLayer?.add(anim, forKey: "animation")
        lay.instanceDelay = anim.duration / Double(lay.instanceCount)
        dots.layer.addSublayer(lay)
    } else if isOn == false {
        circleLayer?.removeAnimation(forKey: "animation")
    }
}
igdev
  • 341
  • 1
  • 4
  • 15