Picking random array elements for button

I have 3 UIButtons, and 3 different variables:

    var firstSign: Sign?

    var secondSign: Sign?

    var thirdSign: Sign?

My goal is to set Title for each button with each variable in random order. I did it for first one and second one, but can't figure out how to add third title. The second one goes as title for Button 2 & 3. This is Quiz game app so first button is additionally marked as rightAnswer.

        rightAnswerPlace = arc4random_uniform(3)+1

        var button: UIButton = UIButton()

        for i in 1...3 {

            button = view.viewWithTag(i) as! UIButton

            if (i == Int(rightAnswerPlace)) {

                button.setTitle(firstSign!.name, for: .normal)

            } else {

                button.setTitle(secondSign!.name, for: .normal)

            }

        }

I know the code above is not completed, but I can't figure out how to add thirdSign variable into the for loop as third button title.

Answered by Claude31 in 740380022

Could you clarify what you want ?

  • You have 3 buttons
  • you define a random rightAnswerPlace
  • you want the button at this position to have the firstSign
  • what do you want for the other 2 ? sign2 and sign3 randomly ?

Could you also explain what view is ?

  • One way to do it:
struct Sign {
    var name: String = ""
}

let firstSign = Sign(name: "first") // Why would it be optional ?
let secondSign = Sign(name: "second")
let thirdSign = Sign(name: "third")

var buttons: [UIButton] = [UIButton(frame: CGRect(x: 20, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 120, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 220, y: 50, width: 80, height: 20))
]

// You will have to add buttons as subviews

var rightAnswerPlace = (0...2).randomElement()!

buttons[rightAnswerPlace].setTitle(firstSign.name, for: .normal)
var remainingPlaces = [0, 1, 2]
remainingPlaces.remove(at: rightAnswerPlace)

let secondSignPlace = remainingPlaces.randomElement()!
for i in remainingPlaces { // Let us set the others
    if i == secondSignPlace {
        buttons[i].setTitle(secondSign.name, for: .normal)
    } else {
        buttons[i].setTitle(thirdSign.name, for: .normal)
    }
}
  • A more direct way to do it is to order the signs randomly. That will allocate "first" at a random position:
struct Sign {
    var name: String = ""
}

let firstSign = Sign(name: "first") // Why would it be optional ?
let secondSign = Sign(name: "second")
let thirdSign = Sign(name: "third")

var signs = [firstSign, secondSign, thirdSign]

var buttons: [UIButton] = [UIButton(frame: CGRect(x: 20, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 120, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 220, y: 50, width: 80, height: 20))
]

// You will have to add buttons as subviews

signs.shuffle() // That puts signs in random order

// And now, assign buttons titles with signs in random order. first will ba at a random position (see after how to find this position)
for (i, button) in buttons.enumerated() {
    button.setTitle(signs[i].name, for: .normal)
}
  • Just to check the result
let rightAnswerPlace = signs.firstIndex(where: { $0.name == "first" })
print("rightAnswer is", rightAnswerPlace!)
for i in 0...2 {
    print(buttons[i].title(for: .normal)!)
}
Accepted Answer

Could you clarify what you want ?

  • You have 3 buttons
  • you define a random rightAnswerPlace
  • you want the button at this position to have the firstSign
  • what do you want for the other 2 ? sign2 and sign3 randomly ?

Could you also explain what view is ?

  • One way to do it:
struct Sign {
    var name: String = ""
}

let firstSign = Sign(name: "first") // Why would it be optional ?
let secondSign = Sign(name: "second")
let thirdSign = Sign(name: "third")

var buttons: [UIButton] = [UIButton(frame: CGRect(x: 20, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 120, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 220, y: 50, width: 80, height: 20))
]

// You will have to add buttons as subviews

var rightAnswerPlace = (0...2).randomElement()!

buttons[rightAnswerPlace].setTitle(firstSign.name, for: .normal)
var remainingPlaces = [0, 1, 2]
remainingPlaces.remove(at: rightAnswerPlace)

let secondSignPlace = remainingPlaces.randomElement()!
for i in remainingPlaces { // Let us set the others
    if i == secondSignPlace {
        buttons[i].setTitle(secondSign.name, for: .normal)
    } else {
        buttons[i].setTitle(thirdSign.name, for: .normal)
    }
}
  • A more direct way to do it is to order the signs randomly. That will allocate "first" at a random position:
struct Sign {
    var name: String = ""
}

let firstSign = Sign(name: "first") // Why would it be optional ?
let secondSign = Sign(name: "second")
let thirdSign = Sign(name: "third")

var signs = [firstSign, secondSign, thirdSign]

var buttons: [UIButton] = [UIButton(frame: CGRect(x: 20, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 120, y: 50, width: 80, height: 20)),
           UIButton(frame: CGRect(x: 220, y: 50, width: 80, height: 20))
]

// You will have to add buttons as subviews

signs.shuffle() // That puts signs in random order

// And now, assign buttons titles with signs in random order. first will ba at a random position (see after how to find this position)
for (i, button) in buttons.enumerated() {
    button.setTitle(signs[i].name, for: .normal)
}
  • Just to check the result
let rightAnswerPlace = signs.firstIndex(where: { $0.name == "first" })
print("rightAnswer is", rightAnswerPlace!)
for i in 0...2 {
    print(buttons[i].title(for: .normal)!)
}

We have it, thank you very much. Sorry if my questions are not fully detailed, but after months of coding practice now I want to learn how to improve it. I've used first way, which fit perfect to the goal and project, optionals stayed with variables to avoid build problems at the beginning, I will improve it at the final stage. I've used this way in IBAction button to check if answer is correct:

 if sender.titleLabel?.text == firstSign.name {
Picking random array elements for button
 
 
Q