I have created a class with random questions however the switch statement does not end and the questions keep going in a loop. How do I prevent this from happening and to display another page once all 4 questions randomly have been completed?
import UIKit
class ThirdViewController: UIViewController {
#IBOutlet weak var Question: UILabel!
#IBOutlet weak var Ans1: UIButton!
#IBOutlet weak var Ans2: UIButton!
#IBOutlet weak var Ans3: UIButton!
#IBOutlet weak var Ans4: UIButton!
#IBOutlet weak var Result: UILabel!
#IBOutlet weak var Next: UIButton!
var correctAns = String()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Hide()
Random()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Random(){
var RandomNumber = arc4random() % 4
RandomNumber += 1
switch (RandomNumber) {
case 1:
Question.text = "Where does minal lives?"
Ans1.setTitle("dubai", for: UIControlState.normal)
Ans2.setTitle("london", for: UIControlState.normal)
Ans3.setTitle("india", for: UIControlState.normal)
Ans4.setTitle("japan", for: UIControlState.normal)
correctAns = "2"
break
case 2:
Question.text = "What is my name?"
Ans1.setTitle("Sunil", for: UIControlState.normal)
Ans2.setTitle("Harish", for: UIControlState.normal)
Ans3.setTitle("Rohit", for: UIControlState.normal)
Ans4.setTitle("Minal", for: UIControlState.normal)
correctAns = "4"
break
case 3:
Question.text = "How old are you?"
Ans1.setTitle("22", for: UIControlState.normal)
Ans2.setTitle("32", for: UIControlState.normal)
Ans3.setTitle("21", for: UIControlState.normal)
Ans4.setTitle("28", for: UIControlState.normal)
correctAns = "1"
break
case 4:
Question.text = "What are you studying?"
Ans1.setTitle("Computer Science", for: UIControlState.normal)
Ans2.setTitle("Java", for: UIControlState.normal)
Ans3.setTitle("Bio", for: UIControlState.normal)
Ans4.setTitle("Business", for: UIControlState.normal)
correctAns = "3"
break
default:
Result.text = "Finished"
break
}
}
func Hide(){
Result.isHidden = true
Next.isHidden = true
}
func Unhide(){
Result.isHidden = false
Next.isHidden = false
}
#IBAction func Ans1Action(_ sender: Any) {
Unhide()
if (correctAns == "1"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func Ans2Action(_ sender: Any) {
Unhide()
if (correctAns == "2"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func Ans3Action(_ sender: Any) {
Unhide()
if (correctAns == "3"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func Ans4Action(_ sender: Any) {
Unhide()
if (correctAns == "4"){
Result.text = "Correct!"
}
else{
Result.text = "Try Again"
}
}
#IBAction func NextAction(_ sender: Any) {
Random()
Hide()
}
}
You need to keep a counter of the number of questions already asked. The switch (RandomNumber) will always enter one of the case statements, because RandomNumber is always in the range 1...4.
So, what you need to do is add an instance variable
private var questionCounter = 0
and modify the NextAction function, something like this:
#IBAction func NextAction(_ sender: Any) {
questionCounter += 1
if questionCounter >= 4 {
Result.text = "Finished"
// or whatever...
}
else {
Random()
Hide()
}
}
Keep in mind that by performing an arc4random() each time, the same question may appear more than once.
Create an array of Int indexes from 1 to 4.
Extract an element from the array and display that item. When the array is empty, stop:
Something like this:
var questionIndexes = [1, 2, 3, 4]
if questionIndexes.count > 0 {
let random = Int(arc4random_uniform(Uint32(questionIndexes.count)))
let index = questionIndexes.remove(at: index)
askQuestionAtIndex(index)
}
(You'll have to adjust the code to fit in with your existing code, but that's the basic idea.)
Related
I've an array of struct, after clicking the correct answer( code below ) I want to change the array index from questions[0] to questions[1], I meant to move through arrays. is it possible in any simple ways ?
any solution will be appericated
var questions:[EasyQuestions] = [
EasyQuestions(question: "1 + 1", optionA: "5", optionB: "2", hint: "3-1", correctAnswer: 1),
EasyQuestions(question: "2 + 2", optionA: "4", optionB: "3", hint: "5-1", correctAnswer: 0)
].shuffled()
override func viewDidLoad() {
super.viewDidLoad()
configure(with: questions[0])
}
#IBAction func buttonClicked(_ sender: UIButton) {
if sender.tag == questions[0].correctAnswer {
print("The answer is correct") // after printing this I want to move on the next element of questions array
}
}
func configure(with question: EasyQuestions){
self.Question.text = question.question
self.button1.setTitle(question.optionA, for: .normal)
self.button2.setTitle(question.optionB, for: .normal)
}
You can try
var currentIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
configure()
}
#IBAction func buttonClicked(_ sender: UIButton) {
if sender.tag == questions[currentIndex].correctAnswer {
print("The answer is correct")
configure()
}
}
func configure(){
if currentIndex < questions.count {
let question = questions[currentIndex]
self.question.text = question.question
self.button1.setTitle(question.optionA, for: .normal)
self.button2.setTitle(question.optionB, for: .normal)
currentIndex += 1
}
}
make sure to set tags of button1 and button2 to 0,1 respectively
In my code for checkmark I used button to change images for selected and unselected but unable to implement if I click on it's changing to unchecked but again selecting button it's unable to change to check image can anyone help me how to resolve this ?
var checkedImage = UIImage(named: "check")! as UIImage
var uncheckedImage = UIImage(named: "uncheck")! as UIImage
var isChecked: Bool = true
var checkMarkSelected = 0
checkMarkButton.addTarget(self, action: #selector(checkMarkAction(button:)), for: .touchUpInside)
func checkMarkAction(button : UIButton) {
if isChecked == true {
checkMarkButton.setImage(checkedImage, for: .selected)
isChecked = false
checkMarkSelected = 1
}
else {
checkMarkButton.setImage(uncheckedImage, for: .normal)
isChecked = true
checkMarkSelected = 0
}
}
Step 1: Select your CheckUIButton and set Image “Uncheck” (state config must be Default in attribute inspector)
Step 2: In attribute inspector change state config to Selected and set image “Check”
Step 3: Put following code in your UIButton action.
#IBAction func checkclick(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
}
In Swift 3
#IBAction func btntouchupInsideevent(_ sender: UIButton)
{
if yourbtnOutletName.currentImage == "YourCheckImageName"
{
yourbtnOutletName.setImage(YourUncheckImage.imagetype, for: .normal)
}
else
{
btnIsEventRecouring.setImage(YourcheckImage.imagetype, for: .normal)
}
}
I think that you should add the action in the viewDidLoad() function of your view controller for that button or, if you are declaring it in a stand-alone UIButton inherited class in order to reuse it in the future in many view controllers, you should add the target in the initialiser of the UIButton.
If the code is written in that way is even strange that Xcode is not giving you warnings...
EDIT: This is a code snippet of how I would do it
//Comments
import UIKit
class ViewController: UIViewController {
//link this to the checkmark buttons
//subclass UIButton making a button with the property isChecked: Bool
#IBOutlet weak var checkmarkButton: UICheckButton!
var checkMarkSelected = 0
override function viewDidLoad() {
//do stuff with your viewdidload
}
//link this to the checkmark buttons
#IBAction func checkMarkAction(sender: UICheckButton) {
if sender.isChecked == false {
let checkedImage = UIImage(named: "check")
checkMarkButton.setImage(checkedImage, for: .normal)
sender.isChecked = true
checkMarkSelected += checkMarkSelected
} else {
let uncheckedImage = UIImage(named: "uncheck")
checkMarkButton.setImage(uncheckedImage, for: .normal)
sender.isChecked = false
checkMarkSelected -= checkMarkSelected
}
}
In Swift 4:
#IBOutlet weak var termsAndConditionsButton: UIButton!
if termsAndConditionsButton.isSelected == true {
termsAndConditionsButton.setImage(UIImage(named: "checkboxOff"), for: .normal)
termsAndConditionsButton.isSelected=false
}
else{
termsAndConditionsButton.setImage(UIImage(named: "checkboxOn"), for: .normal)
termsAndConditionsButton.isSelected=true
}
Try with this on IBAction function
sender.isSelected = !sender.isSelected
if sender.isSelected == true {
sender.isSelected = true
sender.setImage(UIImage(named: "img_on"), for: UIControl.State.selected)
}else{
sender.isSelected = false
sender.setImage(UIImage(named: "img_off"), for: UIControl.State.normal)
}
I have a VC like this
for the checkBoxes i have embedded UIButtons and i am changing their image on click. Here's my code
#IBOutlet weak var bestSellerButton: UIButton!
#IBOutlet weak var trendingButton: UIButton!
#IBOutlet weak var lowToHighButton: UIButton!
#IBOutlet weak var highToLowButton: UIButton!
var isBoxClicked = Bool()
func updateCheckImageOnClick(button: UIButton) {
if isBoxClicked == true {
isBoxClicked = false
button.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
else {
isBoxClicked = true
button.setImage(UIImage(), for: UIControlState.normal)
}
}
#IBAction func clickedBestSellerBtn(_ sender: Any) {
updateCheckImageOnClick(button: bestSellerButton)
}
#IBAction func clickedTrendingBtn(_ sender: Any) {
updateCheckImageOnClick(button: trendingButton)
}
likewise for the rest two. Now the check mark image is being set properly every time on click gets set and unset, but i want to restrict the user like if he clicks on best seller btn he's unable to choose the rest, likewise if he clicks trending he can't select any other. How would i do that?
Make the Other button disabled in particular scenario.
isUserInteractionEnabled = false
You could rename updateCheckImageOnClick(button: UIButton) to something generic in order to add some logic inside, like:
func update(button: UIButton) {
isBoxClicked = !isBoxClicked
button.setImage(isBoxClicked ? UIImage(named: "checkmark") : UIImage(), for: UIControlState.normal)
if button == bestSellerButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == trendingButton {
bestSellerButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == highToLowButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
bestSellerButton.isEnabled = false
} else {
bestSellerButton.isEnabled = false
trendingButton.isEnabled = false
highToLowButton.isEnabled = false
}
}
Usama I've implemented a simple button action for all those buttons which may accomplish your need. Here is the step by step implementation -
First, Declare these variables -
var buttonSelected:Bool = false
var selectedButton : UIButton?
Second, Add a single #IBAction for all buttons -
Third, Here is the action method -
#IBAction func btnSelection(_ sender: UIButton) {
if(buttonSelected){
if(selectedButton == sender){
buttonSelected = false
selectedButton = nil
sender.setImage(UIImage(), for: UIControlState.normal)
}
else{
// It's not the previously selected button
//Do your stuff
}
}
else{
buttonSelected = true
selectedButton = sender
sender.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
}
Hope it will help you to start with.
Im making this Quiz game with pictures on it.
Im trying to add score. Always when you press the right answer, you get one score and when you press wrong answer you must restart the game (that i have been done).
my problem is that where ever I'm trying to put this code, its giving all kind of errors.
So this is the code for highscore:
Score++
ScoreLabel.text = NSString(format: "Score: %i", Score)
if (Score > HighScore){
HighScore = Score
HighScoreLabel.text = NSString(format: "HighScore : %i", HighScore)
and i have put that on this place to the code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var QuestionImage : UIImageView!
#IBOutlet var QuestionLabel: UILabel!
#IBOutlet var Button1: UIButton!
#IBOutlet var Button2: UIButton!
#IBOutlet var Button3: UIButton!
#IBOutlet var Button4: UIButton!
#IBOutlet var Restart: UIButton!
#IBOutlet var LabelEnd: UILabel!
#IBOutlet var ScoreLabel: UILabel!
#IBOutlet var HighScoreLabel: UILabel!
var CorrectAnswer = String()
var Score = 0
var HighScore = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Hide()
RandomQuestions()
HideRestart()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func RandomQuestions(){
var RandomNumber = arc4random() % 2
RandomNumber += 1
switch(RandomNumber){
case 1:
QuestionImage.image = UIImage(named: (“image.jpg"))
QuestionLabel.text = “question?"
Button1.setTitle(“answer", forState: UIControlState.Normal)
Button2.setTitle(“answer", forState: UIControlState.Normal)
Button3.setTitle(“answer", forState: UIControlState.Normal)
Button4.setTitle(“answer", forState: UIControlState.Normal)
CorrectAnswer = "1"
break
case 2:
QuestionImage.image = UIImage(named: (“image2.jpg"))
QuestionLabel.text = “question?"
Button1.setTitle(“answer", forState: UIControlState.Normal)
Button2.setTitle(“answer", forState: UIControlState.Normal)
Button3.setTitle(“answer", forState: UIControlState.Normal)
Button4.setTitle(“answer", forState: UIControlState.Normal)
CorrectAnswer = "3"
break
default:
break
}
}
func Hide(){
LabelEnd.hidden = true
}
func UnHide(){
LabelEnd.hidden = false
}
func HideButtons(){
Button1.hidden = true
Button2.hidden = true
Button3.hidden = true
Button4.hidden = true
}
func HideRestart(){
Restart.hidden = true
}
func UnHideRestart(){
Restart.hidden = false
}
#IBAction func Button1Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "1"){
RandomQuestions()
Hide()
HideRestart()
Score++
ScoreLabel.text = NSString(format: "Score: %i", Score)
if (Score > HighScore){
HighScore = Score
HighScoreLabel.text = NSString(format: "HighScore : %i", HighScore)
}
else{
LabelEnd.text = "You are wrong!"
HideButtons()
UnHideRestart()
}
}
#IBAction func Button2Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "2"){
RandomQuestions()
Hide()
HideRestart()
Score++
ScoreLabel.text = NSString(format: "Score: %i", Score)
if (Score > HighScore){
HighScore = Score
HighScoreLabel.text = NSString(format: "HighScore : %i", HighScore)
}
else{
LabelEnd.text = "You are wrong!"
HideButtons()
UnHideRestart()
}
}
#IBAction func Button3Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "3"){
RandomQuestions()
Hide()
HideRestart()
Score++
ScoreLabel.text = NSString(format: "Score: %i", Score)
if (Score > HighScore){
HighScore = Score
HighScoreLabel.text = NSString(format: "HighScore : %i", HighScore)
}
else{
LabelEnd.text = "You are wrong!"
HideButtons()
UnHideRestart()
}
}
#IBAction func Button4Action(sender: AnyObject) {
UnHide()
if (CorrectAnswer == "4"){
RandomQuestions()
Hide()
HideRestart()
Score++
ScoreLabel.text = NSString(format: "Score: %i", Score)
if (Score > HighScore){
HighScore = Score
HighScoreLabel.text = NSString(format: "HighScore : %i", HighScore)
}
else{
LabelEnd.text = "You are wrong!"
HideButtons()
UnHideRestart()
}
}
}
So always when you press the right button its score and always when wrong, its giving a label "You are wrong!".
And there is these kind of cases for the questions and at the end there is the CorrectAnswer.
I have 4 answer buttons. I also have 2 View Controllers, other is the start screen and second is the game and i would like to get the highscore label on the start view and the score label to the game view.
Thank you very much forehand!
All your ButtonXAction functions are missing their closing parentheses ). You've probably missed one line when copy-pasting...
I am trying a small project in swift.
I have two labels where i get random numbers each time i click a button.
My question is how can I change the title of the button, to the addition of my two random numbers.
Here is the code:
#IBOutlet var number1: UILabel!
#IBOutlet var number2: UILabel!
#IBOutlet var result: UILabel!
var randomNumber1:Int = 0
var randomNumber2:Int = 0
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func generate(sender: AnyObject) {
randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
result.text = "\((randomNumber1) + (randomNumber2))"
}
Try this:
#IBAction func generate(sender: UIButton) {
randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
result.text = "\((randomNumber1) + (randomNumber2))"
sender.setTitle("\((randomNumber1) + (randomNumber2))", forState: UIControlState.Normal)
}
You were missing this line
sender.setTitle("\((randomNumber1) + (randomNumber2))", forState: UIControlState.Normal)
Hope this helps.. :)
btn.setTitle("\(number)", forState: .Normal)
In your current code, you're changing the text of the result label, not the button. To change the UIButton sender's title, change your code to the following:
#IBAction func buttonPress(sender: UIButton) {
let randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
let randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
sender.setTitle("\((randomNumber1) + (randomNumber2))", forState: UIControlState.Normal)
}
Try this code, instead of anyobject use UIButton
#IBAction func generate(sender: UIButton) {
randomNumber1 = Int(arc4random())%11
number1.text = "\(randomNumber1)"
randomNumber2 = Int(arc4random())%11
number2.text = "\(randomNumber2)"
result.text = "\((randomNumber1) + (randomNumber2))"
//Just add this line in the code
sender.setTitle(result.text, forState: UIControlState.Normal)
}