Reputation: 123
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
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 UIView
s will work. You will need to unwrap the UIView?
when reading it later, but since you fill the array with UIView
s, 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 UIView
s.
The advantage is that you'd avoid optional UIView
s, 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
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