BossGiveMeArrays BossGiveMeArrays - 4 months ago 20
Swift Question

Swift iOS. Program crashes when i try to mutate an array of buttons

I have about 20 buttons linked to

allKeys
. I want the turnRed button to change the color of their text to red. I tried the following code:

@IBOutlet var allKeys: [UIButton]!


@IBAction func turnRed(sender: UIButton) {
var i = allKeys.count

repeat {
allKeys[i].setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
i -= 1
} while i != -1
}


When I press the turnRed button, my program crashes and xcode jumps to the appDelegate file and highlights the AppDelegate class with the error Thread1: signal SIGABRT.

The console says "Terminating app due to uncaught exception 'NSRangeException Reason: NSArrayI objectAtIndex

Answer

The issue here is that you are setting the variable i to allKeys.count, but since arrays in swift start with zero, the twentieth element should actually be allKeys[19]. Thus, when the loop is at i = 20, it tries to access allKeys[20], which crashes the app.

One way to solve this is to set i to allKeys.count - 1 instead, but a better way would be to use a for-in loop instead of repeat.

for key in allKeys {
    key.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
}

There are multiple ways to loop in Swift, and you should use the options to your advantage. You can find Apple's documentation for Control Flow here.