1

I'm building a Quiz App and at the end of the quiz, upon clicking an answer, I want the screen to transition to the ResultViewController where the user's score is displayed. I linked a segue from my MCViewController to the new ResultViewController screen. But upon finishing the quiz, the screen just kinda goes dim, no errors.

MCViewController:

 import UIKit

class MCViewController: UIViewController {

@IBOutlet weak var questionLabel: UILabel!
@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet weak var aButton: UIButton!
@IBOutlet weak var bButton: UIButton!
@IBOutlet weak var cButton: UIButton!
@IBOutlet weak var dButton: UIButton!

let quiz =
[
    Questions(q: "When did English settlement begin in Canada?", a: "1510", b: "1497", c: "1604", d: "1720", answer: "1604"),
    Questions(q: "Who passed the Quebec Act of 1774?", a: "Canadian Parliament", b: "British Parliament", c: "Quebec Parliament", d: "The French majority", answer: "British Parliament"),
    Questions(q: "Whose portrait is on the Canadian 10 dollar bill?", a: "Sir George Cartier", b: "Sir Etienne Tache", c: "Sir John A. Macdonald", d: "Sir Louis La Fontaine", answer: "Sir John A. Macdonald"),
    Questions(q: "What are the responsibilities of the federal government?", a: "Matters of national and international concern.", b:  "Matters of national concern.", c: "Matters of international concern.", d: "Matters of provincial concern.", answer: " Matters of national and international concern."),
    Questions(q: "What is 'Habeas corpus'?", a: "The right to challenge unlawful detention by the state.", b: "The right to live and work anywhere in Canada.", c: "The right to speak freely.", d: " The right for peaceful assembly.", answer: "The right to challenge unlawful detention by the state.")
]

var questionNumber = 0

override func viewDidLoad() {
    super.viewDidLoad()
   updateUI()
}

@IBAction func answerPressed(_ sender: UIButton) {
    
    let userAnswer = sender.currentTitle
    let actualAnswer = quiz[questionNumber].answer
    
    if (userAnswer == actualAnswer) {
        sender.backgroundColor = UIColor.green
    } else {
        sender.backgroundColor = UIColor.red   //END OF ARRAY, SHOULD TRANSITION TO RESULTVIEWCONTROLLER
    }
    
    if (questionNumber + 1 < quiz.count){
        questionNumber += 1
    } else {
        let resultVC = ResultViewController()
        self.present(resultVC, animated: true, completion: nil)
    }
    Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
  }

   @objc func updateUI() {
    questionLabel.text = quiz[questionNumber].q
    aButton.setTitle(quiz[questionNumber].a, for: .normal)
    bButton.setTitle(quiz[questionNumber].b, for: .normal)
    cButton.setTitle(quiz[questionNumber].c, for: .normal)
    dButton.setTitle(quiz[questionNumber].d, for: .normal)
    aButton.titleLabel?.adjustsFontSizeToFitWidth = true;
    bButton.titleLabel?.adjustsFontSizeToFitWidth = true;
    cButton.titleLabel?.adjustsFontSizeToFitWidth = true;
    dButton.titleLabel?.adjustsFontSizeToFitWidth = true;
    aButton.backgroundColor = UIColor.clear
    bButton.backgroundColor = UIColor.clear
    cButton.backgroundColor = UIColor.clear
    dButton.backgroundColor = UIColor.clear
    progressBar.progress = Float(questionNumber + 1) / Float(quiz.count)
}
}

ResultViewController:

import UIKit

class ResultViewController : UIViewController{
override func viewDidLoad() {
    super.viewDidLoad()
  }
}

Here's a little bit of my picture if it helps: enter image description here

2 Answers2

0

This code...

let resultVC = ResultViewController()
self.present(resultVC, animated: true, completion: nil)

presents a ResultViewController that is created using the init initialiser, not from the storyboard. It is likely the case that you haven't written anything in ResultViewController.init, because you did everything in the storyboard, so it does nothing and shows a blank view.

Since you have a segue, you should perform that segue instead!

performSegue(withIdentifier: "MCResult", sender: nil)

You probably have some data that you want to pass to ResultViewController. Do that in prepare(for:):

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let vc = segue.destination as? ResultViewController {
        // pass whatever you need to "vc"
    }
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • I just put a label there with some text in the ResultViewController and I used the performSegue line instead, now I get this error: Thread 1: "-[Quizzler_iOS13.ResultViewController initWithIdentifier:source:destination:]: unrecognized selector sent to instance 0x7fdc1920f6c0" – user13205785 Dec 01 '20 at 06:19
  • @user13205785 I just realised you set the segue's class to `ResultViewController`... You should not do that. You can just leave that textfield blank. See [this post](https://stackoverflow.com/questions/33003481/unrecognized-selector-sent-to-instance-error-during-performseguewithidentifier) for more info. – Sweeper Dec 01 '20 at 06:24
0

You are in same storyBoard so, instantiate your viewController like

let resultVC = self.storyboard?.instantiateViewController(withIdentifier: "ResultViewControllerID") as! ResultViewController
self.present(resultVC, animated: true, completion: nil)

I am hoping, you are aware of the UIViewController storyboard ID

  • Follow this [link](https://stackoverflow.com/questions/33099447/sending-data-from-one-uiviewcontroller-to-another-navigationcontroller-using-pre) for passing data – agha Shahriyar Dec 08 '20 at 08:55