4

Why does only one element from the labels array appear as a subview of view, specifically when using Array(repeating:, count:)?

let labels = Array(repeating: UILabel(), count: 7)

print(labels.count) //7

let view = UIView()

for label in labels {
    view.addSubview(label)
}

print(view.subviews.count) //1

test in the Playground

2

2 Answers 2

8

This is the expected behaviour for Array.init(repeating:count:). Think of its implementation as:

// not real code! This is just to illustrate what happens!
init(repeating repeatedValue: Array.Element, count: Int) {
    for _ in 0..<count {
        self.append(repeatedValue)
    }
}

Here, no new labels are created. There are just 7 references pointing to the same label.

It's not useful to create 7 labels this way anyway. They would all be in the same position and have the same size and text. It would look as if there is only one label. So, just use a for loop.

EDIT

Here is an extension that has the behaviour you want:

extension Array {
    init(repeating: (() -> Element), count: Int) {
        self = []
        for _ in 0..<count {
            self.append(repeating())
        }
    }
}

Use it like

Array(repeating: UILabel.init, count: 7)

Since this isn't very useful in creating labels, we can change the closure type to include a Int parameter. This way we can create different labels:

init(repeating: ((Int) -> Element), count: Int) {
    self = []
    for i in 0..<count {
        self.append(repeating(i))
    }
}

// a horizontal row of square labels!
Array(repeating: { UILabel(frame: CGRect(x: $0 * 100, y: 0, width: 50, height: 50)) })

This kinda feels like a for loop now...

Sign up to request clarification or add additional context in comments.

Comments

7

This happens because Array(repeating:count:) creates an array of 7 variables that are pointing to the same label.

Since all 7 elements are pointing to the same instance, the count of the subviews will be 1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.