TheNumberDevil TheNumberDevil - 11 months ago 38
Swift Question

UILabels within an array not showing up on ViewController

So I'm trying to make a grid/table show up in my app, and to do this I created an array of UILabels with:

var rows = 2
var columns = 2

var grid = [[UILabel]](count: rows, repeatedValue: [UILabel](count: columns, repeatedValue: UILabel()))

then I created each UILabel with:

for i in 0 ..< grid.count
for j in 0 ..< grid[0].count
grid[i][j].frame = CGRectMake(x + CGFloat(j*Int(gridSpace)), y + CGFloat(i*Int(gridSpace)), gridSpace, gridSpace)
grid[i][j].backgroundColor = UIColor.redColor()
grid[i][j].hidden = false

grid[i][j].textColor = UIColor.whiteColor()
grid[i][j].textAlignment = NSTextAlignment.Center
grid[i][j].text = "label: [\(i)][\(j)]"


print("grid[\(i)][\(j)]X = \(grid[i][j].frame.origin.x) grid[\(i)][\(j)]Y = \(grid[i][j].frame.origin.y)")

What happens is actually pretty interesting. The code compiles and everything, but only one of the labels shows up. The dimensions and everything about the label are perfect, but only one of them shows up.

The label that shows up is always the grid[rows-1][columns-1] label. But when I print the x and y coordinates of the rest of the labels that are supposed to be in the grid array, all of the coordinates are exactly where they are supposed to be on the viewcontroller it's just that the labels don't show up. when I changed the for loop to

for i in 0 ..< grid.count-1
for j in 0 ..< grid[0].count-1

still only the last label (the grid[rows-1][columns-1] label) shows up yet the coordinates are exactly where they should be. Another weird thing is that if I change the line

grid[i][j].text = "test label: [\(i)][\(j)]"


if(j != grid[0].count-1)
grid[i][j].text = "test label: [\(i)][\(j)]"

then the label that shows up still has the coordinates of the grid[rows-1][columns-1] but has the labeltext of grid[rows-1][columns-2]

Can anyone fix my problem for me or explain whats going on?

Answer Source

It's because of the way that you have initialized your grid with repeated values. If the repeated value is of reference type, the array will actually create only one item and point all indexes to that item, so in your for loops you're changing the frame for the one and only UILabel over and over again. thats why you only see the last one on your screen.

To create the array you want replace this:

var grid = [[UILabel]](count: rows, repeatedValue: [UILabel](count: columns, repeatedValue: UILabel()))


var grid = [[UILabel]]()
for row in 0..<rows {
    for column in 0..<columns{


var grid = [[UILabel]]((0..<rows).map { _ in
        [UILabel]((0..<columns).map { _ in