Terminal
Terminal

Reputation: 123

Swift 3 - 2D Array of UIView

I am trying to create a 2D array of UIViews, Everything seems to be working until I try to fill the array with data. I get the error: "fatal error: Index out of range"

What I currently have:

var gridArray : [[UIView]] = [[UIView]] ()

Now I try to fill the Array with UIViews:

for y in 0 ... 10 {
    for x in 0 ... 10 {

        let cell : UIView!
        cell = UIView(frame: CGRect(x:10, y:10, width:10, height:10))
        self.view?.addSubview(cell)

        gridArray[x][y] = cell
    }
}

Upvotes: 0

Views: 654

Answers (2)

vacawama
vacawama

Reputation: 154613

The problem is that you are creating an array of arrays, but you are not creating the inner arrays. You can't index into an empty array. You could create an 11 x 11 array of UIView? like this:

var gridArray: [[UIView?]] = Array(repeating: Array(repeating: nil, count: 11), count: 11)

Then your code to fill the array with UIViews will work. You will need to unwrap the UIView? when reading it later, but since you fill the array with UIViews, this is a case where a force unwrap will work without crashing.

let cell = gradArray[x][y]!

As @rmaddy noted in the comments, you could use a dummy UIView to initialize the array:

var gridArray: [[UIView]] = Array(repeating: Array(repeating: UIView(), count: 11), count: 11)

This UIView would have 121 references to it, and it would be freed by ARC after all of the references to it were replaced by the real UIViews.

The advantage is that you'd avoid optional UIViews, so no unwrapping would be necessary.

Further, you could then drop the type because Swift would be able to infer it:

var gridArray = Array(repeating: Array(repeating: UIView(), count: 11), count: 11)

Upvotes: 1

OOPer
OOPer

Reputation: 47896

When you initialize an Array with the default initializer, the Array is empty, you cannot subscript to an empty Array.

Before accessing the Array with subscript, you need fill in the actual content to the Array:

    var gridArray: [[UIView]] = []
    for y in 0 ... 10 {
        var rowArray: [UIView] = []
        for x in 0 ... 10 {

            let cell : UIView!
            cell = UIView(frame: CGRect(x:10, y:10, width:10, height:10))
            self.view?.addSubview(cell)

            rowArray.append(cell)
        }
        gridArray.append(rowArray)
    }

Upvotes: 1

Related Questions