BossGiveMeArrays BossGiveMeArrays - 7 months ago 50
Swift Question

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

I have about 20 buttons linked to

. 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


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.