簡體   English   中英

如何遍歷字典,快速按下按鈕加載下一個項目

[英]How to iterate through a dictionary, loading the next item with button press in swift

我正在制作一個應用程序,它會提出一系列問題,在回答是或否時給出一個值。 我有一個帶有問題類型集合視圖的初始視圖控制器。 此視圖控制器將類型信息傳遞給具有問題布局(圖像、標簽、按鈕)的新視圖控制器。 在第二個視圖控制器上,我有一個 switch/case 語句來為傳入的類型提供正確的字典結果(通過 questionTypeReceived),正確填充初始視圖。 一旦你回答了這個問題(簡單的是或否),我想更新下一個問題。 有什么建議可以完成這項工作嗎?

額外信息:我重構了視圖控制器(此處稱為輔助 VC)的問題,因為我最初認為我想重用它,而不僅僅是重新加載它。 除了重新加載下一個問題之外,所有方面都有效......是的,那是因為我沒有代碼來做到這一點。 我一直在不同的地方嘗試不同的 for 循環,但不斷收到錯誤,所以我回到當前設置,因為沒有錯誤

初始風險投資

    let names = [ "Work", "School", "Family", "Friends", "Random" ]

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        questionType = names[indexPath.row] as String
        let storyboard:UIStoryboard = UIStoryboard(name: "questions", bundle: nil)
        let questionsVC = storyboard.instantiateViewController(withIdentifier: "questionsViewController") as! questionsViewController
        questionsVC.questionTypeReceived = questionType
        self.navigationController?.pushViewController(questionsVC, animated: true)
        performSegue(withIdentifier: "question_segue", sender: questionType)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard let dest = segue.destination as? questionsViewController else {
            print("Can't perform downcast")
            return
        }
        dest.questionTypeReceived = questionType
    }

二級VC

    var questionTypeReceived:String = String()
    var answerTotalValue:Double = Double()
    var questionNumber:Int = Int()
    var questionBody = ""
    var questionType = ""

    let answerYesValue:Double = Double.random(in: 1...5)
    let answerNoValue:Double = Double.random(in: 0..<3)

        switch questionTypeReceived {

        case "Random":
            questionTypeReceived = "Random"
            questionsImageView.image = UIImage(named: randomImages.randomElement()!)
            let questionNumber = randomQuestions.keys.sorted()
            let questionBody = randomQuestions.values
            for (questionNumber, questionBody) in randomQuestions {
                questionTitleLabel.text = "Question #\(questionNumber)"
                questionsTextLabel.text = questionBody
            }
        default: return
        }

    let randomQuestions: [Int : String] = [
        1: "Did you already agree to attend?",
        2: "Does it cost money to attend?",
        3: "Is it time consuming (4+ hours)?"
    ]

    @IBAction func yesButtonPressed(_ sender: UIButton) {
        answerTotalValue += answerYesValue
        print(answerTotalValue)
        print(questionTypeReceived)
    }


關於如何處理屬性和局部變量似乎有些混亂,例如,您有 1 個屬性和 2 個名為questionNumber局部變量,並且當我看到您只需要一個問題時,您也在迭代整個字典。

擺脫這種情況的一種方法以及出於其他原因(例如不在控制器類中做所有事情和分離職責)的解決方案也是將問題和對它們的處理移動到單獨的結構或類中。

讓我們創建一個Questions結構來保存問題,跟蹤已經提出的問題,並可以提供下一個要問的問題。

struct Questions {
    private randomQuestions: [Int : String] = [
        1: "Did you already agree to attend?",
        2: "Does it cost money to attend?",
        3: "Is it time consuming (4+ hours)?"
    ]

    private var questionIndex = 0

    mutating func nextQuestion() -> (number: Int, question: String?) {
        questionIndex += 1
        return (questionIndex, randomQuestions[questionIndex])
    }
}

請注意返回元組中字符串的問號,如果索引不存在問題(questionIndex > 3),則返回的問題將為 nil

然后你可以像這樣在你的代碼中使用它,首先在你的 VC 中將它聲明為一個屬性

var questions = Questions()

然后當得到問題

switch questionTypeReceived {
case "Random":
    questionsImageView.image = UIImage(named: randomImages.randomElement()!)
    let nextQuestion = question.nextQuestion()
    if let question = nextQuestion.question {
        questionTitleLabel.text = "Question #\(nextQuestion.number)"
        questionsTextLabel.text = question
    } else {
       // no more questions to ask, this needs to be handled
    }
default: return
}

因此,編寫新結構需要做更多的工作,但是您在 VC 中的代碼變得更簡單,並且不再需要許多屬性和變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM