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
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...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With