我是斯威夫特的新手。我正在嘗試使用 API 制作一個測驗應用程式,我可以顯示一個問題和答案,但我無法繼續下一個問題。我可以通過索引訪問api中的不同問題,但是當我點擊選項時,我無法轉到下一個問題。我查看了類似的應用程式,并觀看了一些如何從 youtube 制作測驗應用程式視頻,但我做不到。
我的測驗經理
import Foundation
protocol quizManagerDelegate {
func didUpdateQuiz(_ Quizmanager: QuizManager ,quiz: QuizModel)
}
struct QuizManager {
var index : Int = 0
var maxQuestion = 14
mutating func nextQuestion(result: Bool) -> Int{
if result == true{
return index 1
} else {
return index
}
}
var delegate: quizManagerDelegate?
func performRequest(){
let urlString = "https://opentdb.com/api.php?amount=15&type=multiple"
if let url = URL(string: urlString){
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { data, response, error in
if error != nil {
print(error!)
return
}
if let safeData = data{
if let quiz = self.parseJSON(quizdata: safeData){
delegate?.didUpdateQuiz(self, quiz: quiz)
}
}
}
task.resume()
}
}
func handle(data: Data?, response: URLResponse?, error: Error?) -> Void {
}
func parseJSON(quizdata: Data) -> QuizModel? {
let decoder = JSONDecoder()
do{
let decodedData = try decoder.decode(Welcome.self, from: quizdata)
let correct = decodedData.results?[index].correct_answer ?? "error"
let quest = decodedData.results?[index].question ?? "error"
let incorrect = decodedData.results?[index].incorrect_answers ?? ["error"]
let question = QuizModel(correctAnswer: correct, question: quest, falseAnswer: incorrect)
return question
} catch {
print(error)
return nil
}
}
mutating func nextQuestion(){
if index 1 < maxQuestion {
index = 1
}else {
index = 0
}
}
}
我的測驗資料
import Foundation
// MARK: - Welcome
struct Welcome: Codable {
let results: [Result]?
}
// MARK: - Result
struct Result: Codable {
let category: String?
let question, correct_answer: String?
let incorrect_answers: [String]?
}
我的測驗模型
import Foundation
struct QuizModel {
let correctAnswer : String
let question : String
let falseAnswer : [String]
}
我的視圖控制器
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var ScoreLabel: UILabel!
@IBOutlet weak var ChoiceButton4: UIButton!
@IBOutlet weak var ChoiceButton3: UIButton!
@IBOutlet weak var ChoiceButton2: UIButton!
@IBOutlet weak var ChoiceButton1: UIButton!
@IBOutlet weak var QuestionTextView: UITextView!
var quizMangager = QuizManager()
var score = 0
var theQuiz: QuizModel?
@IBAction func OptionsButtonPressed(_ sender: UIButton) {
guard let thisQuiz = theQuiz,
let btnTitle = sender.currentTitle
else { return }
if btnTitle == thisQuiz.correctAnswer {
score = 1
ScoreLabel.text = "SCORE: \(score)"
quizMangager.nextQuestion()
sender.setTitleColor(.systemGreen, for: [])
} else {
sender.setTitleColor(.systemRed, for: [])
quizMangager.nextQuestion()
}
Timer.scheduledTimer(timeInterval: 0.35, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
QuestionTextView.text = thisQuiz.question
}
@objc func updateUI() {
}
override func viewDidLoad() {
super.viewDidLoad()
QuestionTextView.layer.cornerRadius = 15
quizMangager.delegate = self
quizMangager.performRequest()
}
}
extension ViewController : quizManagerDelegate{
func didUpdateQuiz(_ Quizmanager: QuizManager, quiz: QuizModel) {
DispatchQueue.main.async { [self] in
self.theQuiz = quiz
self.QuestionTextView.text = quiz.question
var allOptions = []
allOptions.append(quiz.falseAnswer[0])
allOptions.append(quiz.falseAnswer[1])
allOptions.append(quiz.falseAnswer[2])
allOptions.append(quiz.correctAnswer)
let generatedValue = Array(allOptions.shuffled().prefix(4))
print(generatedValue)
print(quiz.correctAnswer)
ChoiceButton1.setTitle(generatedValue[0] as? String, for: .normal)
ChoiceButton2.setTitle(generatedValue[1] as? String, for: .normal)
ChoiceButton3.setTitle(generatedValue[2] as? String, for: .normal)
ChoiceButton4.setTitle(generatedValue[3] as? String, for: .normal)
}
}
}
uj5u.com熱心網友回復:
因為您是“Swift 新手”,所以我將跳過對您的代碼的批評……但有幾點需要注意……
由于您使用的是“新”UIButton樣式,因此您應該使用按鈕配置而不是setTitle()/.setTitleColor()等。
要“繼續下一個問題”,請添加quizManager.performRequest()到您的updateUI()功能。
看看你的ViewController課程的這個修改版本:
class ViewController: UIViewController {
@IBOutlet weak var ScoreLabel: UILabel!
@IBOutlet weak var ChoiceButton4: UIButton!
@IBOutlet weak var ChoiceButton3: UIButton!
@IBOutlet weak var ChoiceButton2: UIButton!
@IBOutlet weak var ChoiceButton1: UIButton!
@IBOutlet weak var QuestionTextView: UITextView!
var quizMangager = QuizManager()
var score = 0
var theQuiz: QuizModel?
@IBAction func OptionsButtonPressed(_ sender: UIButton) {
guard let thisQuiz = theQuiz
else { return }
// disable buttons so user cannot tap more than one
let btns: [UIButton] = [ChoiceButton1, ChoiceButton2, ChoiceButton3, ChoiceButton4]
btns.forEach { btn in
btn.isUserInteractionEnabled = false
}
var cfg = sender.configuration
if let btnTitle = cfg?.title {
if btnTitle == thisQuiz.correctAnswer {
score = 1
ScoreLabel.text = "SCORE: \(score)"
cfg?.baseForegroundColor = .systemGreen
} else {
cfg?.baseForegroundColor = .systemRed
}
}
sender.configuration = cfg
Timer.scheduledTimer(timeInterval: 0.35, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
}
@objc func updateUI() {
quizMangager.nextQuestion()
quizMangager.performRequest()
}
override func viewDidLoad() {
super.viewDidLoad()
QuestionTextView.layer.cornerRadius = 15
quizMangager.delegate = self
quizMangager.performRequest()
}
}
extension ViewController : quizManagerDelegate{
func didUpdateQuiz(_ Quizmanager: QuizManager, quiz: QuizModel) {
DispatchQueue.main.async { [self] in
self.theQuiz = quiz
self.QuestionTextView.text = quiz.question
var allOptions: [String] = []
allOptions.append(quiz.falseAnswer[0])
allOptions.append(quiz.falseAnswer[1])
allOptions.append(quiz.falseAnswer[2])
allOptions.append(quiz.correctAnswer)
let generatedValue = Array(allOptions.shuffled().prefix(4))
print(generatedValue)
print(quiz.correctAnswer)
let btns: [UIButton] = [ChoiceButton1, ChoiceButton2, ChoiceButton3, ChoiceButton4]
// we want to reset buttons
// enabled and title color
// and set the new titles
for (str, btn) in zip(generatedValue, btns) {
var cfg = btn.configuration
cfg?.baseForegroundColor = .white
cfg?.title = str
btn.configuration = cfg
btn.isUserInteractionEnabled = true
}
}
}
}
uj5u.com熱心網友回復:
您的代碼有很多問題需要解決。
我將盡可能詳細地解釋,您需要自己嘗試。
首先,您必須QuizManager進行控制Quiz,但不要將 QuizData 存盤在這里,而是將資料委托給ViewController. 因此,當您更新答案時,您打電話quizMangager.nextQuestion()毫無意義,因為QuizManager不控制或擁有任何資料。
為此,您首先需要重構您的QuizManager.
- 更改
protocol quizManagerDelegate->protocol QuizManagerDelegate以獲得正確的命名約定。 - 當
performRequest您safeData只決議一次并獲得串列結果時。您可以根據需要轉換為串列QuizModel并將其保存在您的QuizManager - 在
QuizManagerDelegate中,只需通知視圖控制器 quizModel 以便更新
protocol QuizManagerDelegate {
func didUpdateQuiz(quiz: QuizModel)
}
在你的performRequest代碼中會是這樣的
self.parseJSON(quizdata: safeData)
delegate?.didUpdateQuiz(quiz:listQuizData[index]) // remember to check if has index
func parseJSON(quizdata: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(Welcome.self, from: quizdata)
let decodedResult = decodedData.results // list result
// you can convert to list quizmodel and save it
// If you do like this just get only one quizModel as each parseJson.
let correct = decodedData.results?[index].correct_answer ?? "error" // remove
let quest = decodedData.results?[index].question ?? "error" // remove
let incorrect = decodedData.results?[index].incorrect_answers ?? ["error"] // remove
let question = QuizModel(correctAnswer: correct, question: quest, falseAnswer: incorrect) // remove
return question // remove
} catch {
print(error)
return nil
}
}
with是您從中決議和轉換的listQuizData串列結果JsonperformRequest
- 最后在
nextQuestion你更新索引后只需要呼叫delegate?.didUpdateQuiz(quiz:listQuizData[index])
來吧ViewController
你只需要拿來QuizModel看看
func didUpdateQuiz(quiz: QuizModel) {
self.theQuiz = quiz
var allOptions : [String] = []
allOptions.append(contentsOf: quiz.falseAnswer) // combine to append only one time
allOptions.append(quiz.correctAnswer)
let generatedValue = Array(allOptions.shuffled().prefix(4))
print(generatedValue)
print(quiz.correctAnswer)
ChoiceButton1.setTitle(generatedValue[0], for: .normal)
ChoiceButton2.setTitle(generatedValue[1], for: .normal)
ChoiceButton3.setTitle(generatedValue[2], for: .normal)
ChoiceButton4.setTitle(generatedValue[3], for: .normal)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/511926.html
標籤:IOS迅速uikit
