0

I'm using the excellent answer here to implement a fade in for a text label.

However, I want to introduce a delay so I can sequentially fade in several text labels.

So far (taken from the answer), i'm using :

extension UIView {

    func fadeIn(duration: TimeInterval = 1.0, delay: TimeInterval = 0.0, completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in}) {
        UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
            self.alpha = 1.0
        }, completion: completion)  }
}

and then implementing with :

override func viewDidLoad() {

        self.line1Outlet.alpha = 0
        self.line1Outlet.fadeIn(completion: {
            (finished: Bool) -> Void in
        })

    }

I was thinking the best solution would be to implement the delay as a parameter in the extension so I could easily add a different delay to each label. (e.g.

override func viewDidLoad() {

        self.line1Outlet.alpha = 0
        //add a parameter here for the delay (here line 1 gets '1second' then line 2 could come in after 2seconds etc)
        self.line1Outlet.delay = 1second
        self.line1Outlet.fadeIn(completion: {
            (finished: Bool) -> Void in
        })

    }

I've tried adding self.delay into the extension (underneath self.alpha) but that doesn't work and I'm not sure how to refactor that extension to allow what I'm after.

The answer to this would then be a reusable method of implementing sequential fades that hopefully would be useful to lots of other people!

nc14
  • 539
  • 1
  • 8
  • 26

1 Answers1

1

In the extension you created, first add self.alpha = 0.0 at the top in fadeIn function, i.e.

extension UIView {
    func fadeIn(duration: TimeInterval = 1.0, delay: TimeInterval = 0.0, completion: ((Bool)->())? = nil) {
        self.alpha = 0.0
        UIView.animate(withDuration: duration, delay: delay, options: .curveEaseIn, animations: {
            self.alpha = 1.0
        }, completion: completion)
    }
}

Now lets assume you've 3 labels in your view, i.e.

@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!

Add animation to the labels in sequence like,

self.label1.fadeIn(delay: 0.1) { _ in
    self.label2.fadeIn(delay: 0.2, completion: { _ in
        self.label3.fadeIn(delay: 0.3, completion: { _ in
            print("Done All")
        })
    })
}

Since the duration parameter in fadeIn method is having a default value, we can avoid that.

The way you're calling fadeIn is one way of calling it. Since the method contains multiple default params, it can be called in other ways as well.

Read more about default parameters here.

enter image description here

Edit:

For hiding the labels initially, set the alpha of all labels as 0 in storyboard itself.

enter image description here

PGDev
  • 23,751
  • 6
  • 34
  • 88
  • hmm this isn't working for me in simulator, the print statement is working but no animation is happening – nc14 Jun 12 '19 at 11:04
  • Set the alpha of all the label as 0 initially. Also see the gif I've added. – PGDev Jun 12 '19 at 11:09
  • thanks - this is working better now but I'm getting it where all labels are displayed. then each is disappearing and then fading in with the right delay values. How do I make it so they are hidden initially? I've set alpha = 0 at the top like you said – nc14 Jun 12 '19 at 11:14
  • For hiding them initially, set the alpha of all labels as 0 in storyboard itself.. – PGDev Jun 12 '19 at 11:16
  • ah right okay - is there a way to set that in the model (I thought that was what the self.alpha = 0 should do on this line). So that, if a label has fade in applied, it also sets it to 0 initially? No worries if not , this works great and I will mark this as correct func fadeIn(duration: TimeInterval = 1.0, delay: TimeInterval = 0.0, completion: ((Bool)->())? = nil) { self.alpha = 0.0 – nc14 Jun 12 '19 at 11:20
  • You can use a model. But you still need to apply that to your UI element either in storyboard or programatically. – PGDev Jun 12 '19 at 11:22
  • is this able to be modified to start the delay from the time the function is loaded rather than starting it once the previous one has finished? i.e. so there isn't a minimum of one second (the time it takes for the animation to complete) between them starting to fade in? – nc14 Jun 14 '19 at 12:42