Search code examples
arraysswiftinitializationdeclarationvar

declare var as a group in swift


I want to declare a group of the same objects like this.

var dave, paul, sam = UILabel()

I have tried various things. But I have not been able to do anything different to declare vars except the standard.

var dave = UILabel()
var paul = UILabel()
var sam = UILabel()

I would think there has to be someway to put this in a array to speed up the process.


Solution

  • Rather than using named variables, you can just create an array of labels:

    let labels = (0..<3).map { _ in UILabel() }
    

    Or you might as well configure them as you create them:

    let labels = (0..<3).map { _ -> UILabel in 
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }
    

    You can do whatever other configuration of them you want in that closure.

    Now you can use them. For example, you might add them to your view which already has a vertical stack view (which gets you out of the business of manually adding constraints for each label), like so:

    func viewDidLoad() {
        super.viewDidLoad()
    
        for label in labels {
            stackView.addArrangedSubview(label)
        }
    }
    

    And if you wanted to set the text for these labels:

    labels[0].text = "Dave"
    labels[1].text = "Paul"
    labels[2].text = "Sam"
    

    Here is a playground that illustrates the above:

    import UIKit
    import PlaygroundSupport
    
    class ViewController: UIViewController {
        let stackView: UIStackView = {
            let stackView = UIStackView()
            stackView.translatesAutoresizingMaskIntoConstraints = false
            stackView.axis = .vertical
            return stackView
        }()
    
        let labels = (0..<3).map { _ -> UILabel in 
            let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false
            return label
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            addStackView()
            addLabels()
            updateLabels()
        }
    }
    
    private extension ViewController {
        func addStackView() {
            view.addSubview(stackView)
            NSLayoutConstraint.activate([
                stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
            ])
        }
    
        func addLabels() {
            for label in labels {
                stackView.addArrangedSubview(label)
            }
        }
    
        func updateLabels() {
            labels[0].text = "Dave"
            labels[1].text = "Paul"
            labels[2].text = "Sam"
        }
    }
    
    PlaygroundPage.current.liveView = ViewController()
    

    Now, if this was a proper app rather than a playground, I’d probably just add the stack view in IB, with an @IBOutlet, rather than doing it programmatically, but I just wanted to illustrate the idea.