2

I have a label that is initially positioned at the center of the screen. It currently transitions from the the center to the right end of the screen then autoreverses back to its position. I'd like to have it begin another animateWithDuration so that it continues from the center return to the left position of the screen then autoreverse back to the position and sequentially loop from there on after.

I have already attempted and successfully made the first half work but I'm not sure how to continue to the second portion where it begins the center->left transition and loop.

Swift 2.0 Code:

   func animateRight()
    {
        UIView.animateWithDuration(1.0, delay: 0.0, options: [ .Autoreverse, .CurveEaseInOut], animations: {
                label.center.x = self.view.frame.width/2
            }, completion: { finished in
                if finished {
                    label.frame.origin.x = 0.0
                    animateLeft()
                }
        })
    }

    func animateLeft()
    {
        UIView.animateWithDuration(1.0, delay: 0.0, options: [ .Autoreverse, .CurveEaseInOut], animations: {
                label.frame.origin.x = (self.view.frame.width/2) * -1
            }, completion: { finished in
                if finished {
                    label.center.x = self.view.frame.width/2
                    animateRight()
                }
        })
    }

    // Start process
    animateRight()
theflarenet
  • 642
  • 2
  • 13
  • 27

2 Answers2

3

You should call the same animate with duration method you create for animating to right and call in completion. Something like this:

func animateRight()
{
    UIView.animate(withDuration: 1.0, delay: 0.0, options: [], animations: {
        self.label.center.x = self.view.frame.width
    }, completion: { finished in
        if finished {
            self.animateLeft()
        }
    })
}

func animateLeft()
{
    UIView.animate(withDuration: 2.0, delay: 0.0, options: [ .autoreverse, .repeat, .curveEaseInOut, .beginFromCurrentState], animations: {
        self.label.frame.origin.x = 0.0
    }, completion: nil)
}
Karen Hovhannisyan
  • 1,140
  • 2
  • 21
  • 31
Vitalii Boiarskyi
  • 1,363
  • 2
  • 10
  • 25
  • This is good! I have made it a step further but it's functioning incorrectly. I am okay about this whole loop lasting forever because it's just an animation that will repeat infinitely for visual effects. I have updated my code and, currently, it runs animateRight() and sequentially runs animationLeft(); but animationLeft() loops and never calls animateRight() as expected. – theflarenet Apr 24 '16 at 06:07
  • I have updated the code. So now animate to the right doesn't use .Autoreverse but ends in the right. And then left animation get called with .Autoreverse and .Repeat – Vitalii Boiarskyi Apr 24 '16 at 07:06
  • 1
    Excellent! Thank you! – theflarenet Apr 24 '16 at 07:33
0
  • Call defaultSetup to start
  • When animationRight end, it will call animationLeft
  • When animationLeft end, it will call animationRight again to run animation loop

Here is the code:

    func defaultSetup(){
        
        self.animationRight()
    }
    
    func animationRight(){
        
        let transform = CGAffineTransform(scaleX: 1.05, y: 1.05).rotated(by: .pi/180)
        UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 3.0, options: [.allowUserInteraction, .repeat], animations: { [weak self] in
            guard let `self` = self else { return }
            self.vRight.transform = transform
            
        }, completion: { [weak self] (done) in
            guard let `self` = self else { return }
            self.vRight.transform = .identity
            self.animationLeft()
        })
    }
    
    func animationLeft(){
        let transform = CGAffineTransform(scaleX: 1.05, y: 1.05).rotated(by: .pi/180)
        UIView.animate(withDuration: 3.0, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 3.0, options: [.allowUserInteraction], animations: { [weak self] in
            guard let `self` = self else { return }
            self.vLeft.transform = transform
            
        }, completion: { [weak self] (done) in
            guard let `self` = self else { return }
            self.vLeft.transform = .identity
            self.animationRight()
        })
    }
QuangLoc
  • 71
  • 1
  • 4