Joe
Joe

Reputation: 3961

animateWithDuration - FadeIn/FadeOut animation in UITextField

I have a score counter in an app I am working on. Rather than just changing the number, I would like the transition to fade the new score in, while the old score scales up and fades out.

The following is as close as I got:

     UIView.animateWithDuration(0.6, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {

        self.scoreOutlet.text = "\(self.numberFormatter.stringFromNumber(self.score)!)"
        self.scoreOutlet.transform = CGAffineTransformMakeScale(1.5, 1.5)
        self.scoreOutlet.alpha = 0.0

        }) { (_) in
            UIView.animateWithDuration(0.0, animations: {

                self.scoreOutlet.transform = CGAffineTransformMakeScale(1.0, 1.0)
                self.scoreOutlet.alpha = 1.0

            })
    }

I would like these to happen simultaneously. I realize that the closure occurs after the 0.6 seconds of the initial animation, but didn't think nesting animateWithDuration blocks is the cleanest approach here..

Desired Result

If the score changes from 20 to 25: 25 would fade in, but at the same time, 20 is fading out, scaling larger, and slightly moving up (the slightly moving up part isn't in my code attempt above.)

Upvotes: 1

Views: 779

Answers (2)

4oby
4oby

Reputation: 607

Make 2 labels, 1 for the old score 1 for the new, this way both can be done in 1 animation, and in the completion, set the new score to the oldScoreLabel so the other one is ready when ether you'll update the score.

you should get something like this:

 UIView.animateWithDuration(0.6, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
        self.scoreOutlet.alpha = 0.0

        self.newScoreOutlet.text = "\(self.numberFormatter.stringFromNumber(self.score)!)"
        self.newScoreOutlet.transform = CGAffineTransformMakeScale(1.5, 1.5)
        self.newScoreOutlet.alpha = 1.0

        }) { (_) in
            UIView.animateWithDuration(0.0, animations: {

                self.newScoreOutlet.transform = CGAffineTransformMakeScale(1.0, 1.0)
                self.newScoreOutlet.alpha = 0.0

                self.scoreOutlet.alpha = 1.0
                self.scoreOutlet.text = self.newScoreOutlet.text
            })
    }

Upvotes: 2

Ozgur Vatansever
Ozgur Vatansever

Reputation: 52133

A relatively ugly solution to this would be placing two labels onto text field which represent fading-in and fading-out views respectively and then you animate them by tweaking their transform and alpha properties.

First we need to find the frame of where the text is placed within the text field:

let textRect = textField.textRectForBounds(textField.bounds)

Then, we create the labels and add them into the textField:

let fadeOutTextLabel = UILabel(frame: textRect)
fadeOutTextLabel.text = textField.text
fadeOutTextLabel.textColor = textField.textColor
fadeOutTextLabel.font = textField.font

let fadeInTextLabel = UILabel(frame: textRect)
fadeInTextLabel.text = textField.text == "20" ? "25": "20"
fadeInTextLabel.textColor = textField.textColor
fadeInTextLabel.font = textField.font

fadeInTextLabel.alpha = 0.0
fadeInTextLabel.transform = CGAffineTransformMakeScale(1.5, 1.5)

textField.addSubview(fadeInTextLabel)
textField.addSubview(fadeOutTextLabel)

--

Since scaling a view might cause it to expand beyond its superview's frame, we should set clipsToBounds to false to prevent it from getting clipped:

textField.clipsToBounds = false

--

In the animation block, all we need to do is swapping transform and alpha values of two labels:

UIView.animateWithDuration(
  0.7,
  animations: {
    fadeOutTextLabel.transform = CGAffineTransformMakeScale(1.5, 1.5)
    fadeOutTextLabel.alpha = 0.0

    fadeInTextLabel.transform = CGAffineTransformIdentity
    fadeInTextLabel.alpha = 1.0
  },
  completion: { finished in
    fadeOutTextLabel.removeFromSuperview()
    fadeInTextLabel.removeFromSuperview()

    self.textField.clipsToBounds = true
    self.textField.text = fadeInTextLabel.text
})

--

enter image description here

You can download the sample project from here.

Upvotes: 2

Related Questions