为什么只有labels数组中的一个元素显示为的子视图view,特别是在使用时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
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为Array(repeating:count:)创建了一个包含 7 个指向同一标签的变量的数组。
由于所有 7 个元素都指向同一个实例,因此子视图的数量将为 1。
这是的预期行为Array.init(repeating:count:)。将其实现视为:
// not real code! This is just to illustrate what happens!
init(repeating repeatedValue: Array.Element, count: Int) {
for _ in 0..<count {
self.append(repeatedValue)
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,没有创建新标签。只有7个引用指向相同的标签。
无论如何用这种方法创建7个标签是没有用的。它们都将处于相同的位置,并具有相同的大小和text。看起来好像只有一个标签。因此,只需使用for循环。
编辑
这是具有所需行为的扩展:
extension Array {
init(repeating: (() -> Element), count: Int) {
self = []
for _ in 0..<count {
self.append(repeating())
}
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用
Array(repeating: UILabel.init, count: 7)
Run Code Online (Sandbox Code Playgroud)
由于这在创建标签中不是很有用,因此我们可以更改闭包类型以包含Int参数。这样,我们可以创建不同的标签:
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)) })
Run Code Online (Sandbox Code Playgroud)
现在有点像for循环了...