I do not have any experience with programing. I have done this looking at youtube videos for a couple of months. I will really appreciate if someone can please help me. When I run the code with the simulator it repeats the questions several time before the next new question is presented. I would like it to run so it presents one question without repeating the same question over and over. Below please find the code.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var QuestionLabel: UILabel!
@IBOutlet weak var Button1: UIButton!
@IBOutlet weak var Button2: UIButton!
@IBOutlet weak var Button3: UIButton!
@IBOutlet weak var Button4: UIButton!
@IBOutlet weak var Next: UIButton!
@IBOutlet weak var LabelEnd: UILabel!
var CorrectAnswer = String()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Hide()
RamdomQuestions()
}
func RamdomQuestions () {
var RandomNumber = arc4random() % 4
RandomNumber += 1
switch (RandomNumber) {
case 1:
QuestionLabel.text = "Hola familia, Cual es mi nombre? "
Button1.setTitle ("Cesar", forState: UIControlState.Normal)
Button2.setTitle ("Karlos", forState: UIControlState.Normal)
Button3.setTitle ("William", forState: UIControlState.Normal)
Button4.setTitle ("Chiqui", forState: UIControlState.Normal)
CorrectAnswer = "2"
break
case 2:
QuestionLabel.text = "Hola famili, cual es mi apellido? "
Button1.setTitle ("Perez", forState: UIControlState.Normal)
Button2.setTitle ("Carvajal", forState: UIControlState.Normal)
Button3.setTitle ("Garcia", forState: UIControlState.Normal)
Button4.setTitle ("Sanchez", forState: UIControlState.Normal)
CorrectAnswer = "1"
break
case 3:
QuestionLabel.text = "Quien hace la lachona mas rica? "
Button1.setTitle ("Willy", forState: UIControlState.Normal)
Button2.setTitle ("Mario", forState: UIControlState.Normal)
Button3.setTitle ("Karlos", forState: UIControlState.Normal)
Button4.setTitle ("Juan David", forState: UIControlState.Normal)
CorrectAnswer = "1"
break
case 4:
QuestionLabel.text = "Quien hace las tartas mas lindas"
Button1.setTitle ("Jili", forState: UIControlState.Normal)
Button2.setTitle ("Carvajal", forState: UIControlState.Normal)
Button3.setTitle ("Garcia", forState: UIControlState.Normal)
Button4.setTitle ("Leidy y Liz", forState: UIControlState.Normal)
CorrectAnswer = "4"
break
default:
break
}
}
func Hide (){
LabelEnd.hidden = true
Next.hidden = true
}
func UnHide () {
LabelEnd.hidden = false
Next.hidden = false
}
@IBAction func Button1Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "1") {
LabelEnd.text = "Correcto"
}
else{
LabelEnd.text = "Falso"
}
}
func Button2Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "2") {
LabelEnd.text = "Correcto"
}
else{
LabelEnd.text = "Falso"
}
}
func Button3Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "3") {
LabelEnd.text = "Correcto"
}
else{
LabelEnd.text = "Falso"
}
}
func Button4Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "4") {
LabelEnd.text = "Correcto"
}
else{
LabelEnd.text = "Falso"
}
}
@IBAction func Next(sender: AnyObject) {
RamdomQuestions()
}
}
The typical solution for this is to have an array of questions (or indexes into your model) and then shuffle this array so it's random. You can then iterate through this shuffled array of questions, and they'll appear in a largely random fashion, but you don't have to worry about them reappearing.
In Swift 4.2, you'd use the built-in
shuffle
orshuffled
methods to shuffle your array.In Swift versions before 4.2, you have to shuffle the array yourself. Note, when generating a random number, you should not use
arc4random
with the%
operator. That introduces modulo bias. Instead, usearc4random_uniform
which generates uniformly distributed random numbers within a range of values. And shuffling the array, you should use a Fisher-Yates algorithm, which eliminates some subtle biases introduced by naive shuffling algorithms. For general information, see the Fisher-Yates article in Wikipedia. For specific Swift implementation, see How do I shuffle an array in Swift?. Anyway, the algorithm looks like:You can then use it like so:
You end up with an array of the numbers 0 through n-1 that are shuffled (i.e. appear in a random order, but no number occurs more than once). You can now iterate through this array of
questionIndexes
and each question will be asked once and only once, but they'll be presented in random order.A couple of unrelated observations:
You probably want to adopt Cocoa naming conventions, namely that method and property names should always start with a lowercase letter. Only data types (e.g. classes or structs) and enums start with uppercase letters.
When doing a
switch
statement in Swift, you don't needbreak
. Swift doesn't fall through like Objective-C does. When I tackled point 5, below, it turns out I ended up factoring out theswitch
statement entirely, but just for your future reference, you don't need tobreak
at the end of eachcase
in Swift like you did in C-based programming languages like Objective-C. In fact, if you want a Swiftcase
statement to fall through to the next one, like it does in Objective-C, you'd have to use thefallthrough
keyword.You probably shouldn't initialize
correctAnswer
asString()
. Just declare it to be an optional (an implicitly unwrapped one, if you want).Even better,
correctAnswer
should be anInt
rather than aString
. I'd also use a zero-based value so that I can easily look up the value to confirm whether the right button was pressed.This is a more advanced topic, but I'd suggest separating the "model" (i.e. the data about question text, potential answers, and correct answer) from "controller" (the code that takes information from the model and updates the view). This is part of the model-view-controller paradigm that we use in our apps. It makes your app easier to maintain in the future (e.g. you can add more questions, change questions, etc., but not have to touch the code in the view controller). It also enables more flexible patterns (e.g. the questions and answers could be provided by a remote web service or be stored in a database).
For example, you might have a type that captures the question, its potential answer, and identifies which is the correct answer.
Your model might then consist of an array of
Question
objects:Note, forgive my changing the "correct answer" in these questions from that which was presented in your question. I just wanted to illustrate that we're dealing with numbers from
0
through3
(not1
through4
).Pulling this all together, you might have an implementation that looks like:
There's a lot buried in there, so I wouldn't worry about the details if you don't quite follow everything that's going on here. But the key is, build an array of indexes into your model, shuffle it, and then you can proceed to iterate through this shuffled array and you're guaranteed that you won't ask the same question twice.