如何从类中的数组中提取不同的项?

时间:2019-01-13 06:13:06

标签: swift

我正在创建具有多个类别的测验应用程序。如果用户希望选择一个类别,则他们将“打开”该类别的开关。然后,如果开关打开,则布尔值将设置为true;如果关闭,则将布尔值设置为false。然后,该Bool值将被发送到下一个视图控制器,如果该控制器具有真值,则该函数将运行一个函数,该函数会将所选类别的问题的数组添加到保存所选类别的数组的数组中。

当前,这是我的应用程序的功能: 我有一个名为Question的快速文件,该文件为问题的基本结构创建了一个类。然后,我有另一个名为QuestionBank的文件,其中包含一个类,并且在该类中是我使用Question.swift文件中的类创建的问题数组。从那里开始,在我的游戏的视图控制器中,我调用包含问题数组的类,然后我的代码按照在数组中被调用的顺序显示每个问题及其所有选项。如何使用户能够根据用户输入访问数组中的特定问题或特定问题组?我已经尝试创建多个问题数组,然后尝试将它们组合起来,以便可以对这两个类别的用户进行测试,但是由于某种原因,我无法这样做。

第一视图控制器:

import UIKit


class ViewControllerTrivia: UIViewController {
    var historySelection = Bool()

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let gameController = segue.destination as! ViewControllerGame
    gameController.isHistorySelected = historySelection
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        // Do any additional setup after loading the view.
    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

    @IBAction func swipeToHome(_ sender: Any) {
        performSegue(withIdentifier: "triviaToHome", sender: ViewControllerHome.self)}

    @IBAction func startGame(_ sender: Any) {
        performSegue(withIdentifier: "triviaToGame", sender: ViewControllerGame.self)
    }

    @IBAction func historySelectionSwitch(_ sender: UISwitch) {

        if (sender.isOn == true) {
            var historySelection = true
            print("on")
        } else {
            var historySelection = false
            print("off")
        }

    }
}

Second View Controller:

import UIKit



class ViewControllerGame: UIViewController {
    var isHistorySelected = Bool()
    @IBOutlet weak var questionCounter: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!
    @IBOutlet weak var progressView: UIView!
    @IBOutlet weak var questionLabel: UILabel!

    //Outlet for Buttons
    @IBOutlet weak var optionA: UIButton!
    @IBOutlet weak var optionB: UIButton!
    @IBOutlet weak var optionC: UIButton!
    @IBOutlet weak var optionD: UIButton!

    var allQuestions = [(Question(questionText: "History: What does FBLA stand for?", choiceA: "A. Formidable Business Learners of America", choiceB: "B. Future Business Learners of America", choiceC: "C.Future Business Leaders of America", choiceD: "D.Fleeting Business Learners Of America", answer: 3)),]
    var historyQuestions = [(Question(questionText: "History: Who was the founder of the FBLA program?", choiceA: "A. Edward D. Miller", choiceB: "B. Conrad N. Hilton", choiceC: "C. Hamden L. Forkner", choiceD: "Elena Daly", answer: 3)) ]

    var questionNumber: Int = 0
    var score: Int = 0
    var selectedAnswer: Int = 0

    func questionSelection() {
        if isHistorySelected == true{
            allQuestions.append(contentsOf: historyQuestions)
        }
    }

    //Making only the top corners of the progress view visible
    func roundProgressCorners() {
    self.progressView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        roundProgressCorners()
        questionSelection()
        updateQuestion()
        updateUI()

        // Do any additional setup after loading the view.
    }

    @IBAction func answerPressed(_ sender: UIButton) {
        if sender.tag == selectedAnswer{
            print("correct")
            score += 1
        }else {
            print("wrong")
        }
        questionNumber += 1
        updateQuestion()

    }
    func updateQuestion(){

        if questionNumber <= allQuestions.count - 1{
            questionLabel.text = allQuestions[questionNumber].question
            optionA.setTitle(allQuestions[questionNumber].optionA, for: UIControl.State.normal)
            optionB.setTitle(allQuestions[questionNumber].optionB, for: UIControl.State.normal)
            optionC.setTitle(allQuestions[questionNumber].optionC, for: UIControl.State.normal)
            optionD.setTitle(allQuestions[questionNumber].optionD, for: UIControl.State.normal)
            selectedAnswer = allQuestions[questionNumber].correctAnswer
            updateUI()

        }else {
            restartQuiz()
            performSegue(withIdentifier: "gameToEndScreen", sender: ViewControllerEndScreen.self)
        }


    }
    func updateUI(){
        scoreLabel.text = "Score: \(score)"
        questionCounter.text = "\(questionNumber + 1)/\(allQuestions.count)"
        progressView.frame.size.width = (view.frame.size.width / CGFloat(allQuestions.count)) * CGFloat(questionNumber + 1)

    }
    func restartQuiz(){
        score = 0
        questionNumber = 0
        updateQuestion()

    }


}

对于最终结果,我希望用户能够选择要查询的类别,然后该应用程序将合并所选的类别。

1 个答案:

答案 0 :(得分:0)

您将不得不重新设计数据结构,尽管有以下内容,这可能对您有所帮助,或者您可以得到更多的想法。

//1. Create an enum of Question Category
enum QuestionCatgory: String{
    case Sports = "Sports"
    case Politics = "Politicd"
    case Science = "Science"
}

//2. Create a Structure that will hold details about each Question, including its category
struct QuestionsDetail{
    let question: String
    let options: [String]
    let currectOption: Int
    let category: QuestionCatgory

    init(question: String, options: [String], correctOption: Int, category: QuestionCatgory){
        self.question = question
        self.options = options
        self.currectOption = correctOption
        self.category = category
    }
}

class ViewController: UIViewController {

    var questionList: [QuestionsDetail] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        //3. Create data source of your question. Preferably get this data from backend or store it in a Plist or JSON file for better maintainability. In this example its hardcoded
        questionList = createDataSource()

        //4. Call this method to get questions specific for a Category. You can use this array to populate the question in a ViewController. Use delegate to capture user response to maintain the scorecard and other things
        let questionListOfCategory = getQuestionsList(forCategory: .Science)

        print("Questions List for:\n\(questionListOfCategory)\n")

    }

    func getQuestionsList(forCategory category: QuestionCatgory) -> [QuestionsDetail]{

        var questionListOfCategory: [QuestionsDetail] = []

        for question in questionList {
            if question.category.rawValue == category.rawValue{
                questionListOfCategory.append(question)
            }
        }

        return questionListOfCategory
    }

    func createDataSource() -> [QuestionsDetail]{
        let questionDetail1 = QuestionsDetail(question: "Question1", options: ["Option1 A", "Option1 B", "Option1 C", "Option1 D"], correctOption: 2, category: .Sports)
        let questionDetail2 = QuestionsDetail(question: "Question2", options: ["Option2 A", "Option2 B", "Option2 C", "Option2 D"], correctOption: 4, category: .Politics)
        let questionDetail3 = QuestionsDetail(question: "Question3", options: ["Option3 A", "Option3 B", "Option3 C", "Option3 D"], correctOption: 1, category: .Science)
        let questionDetail4 = QuestionsDetail(question: "Question4", options: ["Option4 A", "Option4 B", "Option4 C", "Option4 D"], correctOption: 3, category: .Sports)
        let questionDetail5 = QuestionsDetail(question: "Question5", options: ["Option5 A", "Option5 B", "Option5 C", "Option5 D"], correctOption: 4, category: .Politics)

        var questionList: [QuestionsDetail] = []

        questionList.append(questionDetail1)
        questionList.append(questionDetail2)
        questionList.append(questionDetail3)
        questionList.append(questionDetail4)
        questionList.append(questionDetail5)

        return questionList
    }


}