NoKey
NoKey

Reputation: 403

Animate every element in one UIView

I want to animate every UIButton/UILabel in a UIView. For example that every UIButton fades in one after another, with a single line of code. Is this possible? I searched on Github but I could not find anything. I find it a lot of work animating every single UILabel or UIButton one by one. Thank you.

Upvotes: 0

Views: 228

Answers (3)

Eendje
Eendje

Reputation: 8883

let duration = 0.5

view.subviews.flatMap { $0 as? UILabel ?? $0 as? UIButton }.enumerated().forEach { i, o in UIView.animate(withDuration: duration, delay: Double(i) * duration, animations: { o.alpha = 0 }) }

In "one" line.

Typed this on my phone so if I made some errors pls feel free to correct them :)

Upvotes: 2

Rikh
Rikh

Reputation: 4222

You can do it on your own by iterating over subviews of a UIView and checking if its a UILabel or UIButton! Do something like:

var counter : Double = 0

func hideSubviews(view:UIView){

    for tempView in view.subviews{

        let when = DispatchTime.now() + counter

        if tempView is UIButton || tempView is UILabel{

            DispatchQueue.main.asyncAfter(deadline: when) {

                UIView.animate(withDuration: 1, animations: {
                    //this does fade out, change 0 to 1 for fade in
                    tempView.alpha = 0.0
                })
            }
        }
        //increment by gap you want
        counter += 1
    }
}

Edit:

Sigh I forgot about this much simpler way, you can use the delay property in the animate function:

var counter = 0

func hideSubviews(view:UIView){

    for tempView in view.subviews{

        if tempView is UIButton || tempView is UILabel{

            UIView.animate(withDuration: 0.3, delay: TimeInterval(counter), options: .init(rawValue: 0), animations: {

                tempView.alpha = 0.0

            }, completion: nil)
        }

        counter += 1
    }
}

And then in your viewDidAppear or wherever, just call the function and pass in the view:

override func viewDidAppear(_ animated: Bool) {

     super.viewDidAppear(animated)

     hideSubviews(view: view)
}

Upvotes: 1

gwinyai
gwinyai

Reputation: 2580

You could create and call a function as the single line of code you are looking for, where you add an array of the buttons or labels you want faded in. I will give you an example you can copy paste and it should work. The only thing you need to do is to hook up the UIButton outlets in Storyboard.

    import UIKit

class ViewController: UIViewController {

@IBOutlet weak var button1: UIButton!

@IBOutlet weak var button2: UIButton!

@IBOutlet weak var button3: UIButton!

var count = 0

override func viewDidLoad() {
    super.viewDidLoad()

}

override func viewDidAppear(_ animated: Bool) {

    let allButtons = [button1, button2, button3]

    fadeInButtons(buttons: allButtons as! [UIButton])

}

func fadeInButtons(buttons: [UIButton]) {

    UIView.animate(withDuration: 0.4, animations: {

            buttons[self.count].alpha = 0


    }) { (value) in

        if self.count < buttons.count - 1 {

            self.count += 1

            self.fadeInButtons(buttons: buttons)

        }

       }





}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

Your Storyboard with the buttons should look like this

Storyboard

So all you need to do is call the function fadeInButtons(buttons: [UIButton]) and pass it an array of the buttons you want to fade in and it will do so one after the next. You can modify this to also include labels func fadeInButtons(buttons: [UIButton], labels: [UILabel]). You can modify the time of each animation, in this example each fade in animation takes 0.4 to complete.

Upvotes: 1

Related Questions