refactor: rename ViewModel to QuizViewModel
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class ViewModel: ObservableObject {
|
class QuizViewModel: ObservableObject {
|
||||||
|
|
||||||
@Published var questions: [QuizQuestion] = []
|
@Published var questions: [QuizQuestion] = []
|
||||||
@Published var selectedCategory: String? = nil
|
@Published var selectedCategory: String? = nil
|
||||||
@@ -12,7 +12,7 @@ struct EstimationQuestionView: View {
|
|||||||
let maxValue: Double
|
let maxValue: Double
|
||||||
let correctValue: Double
|
let correctValue: Double
|
||||||
let unit: String
|
let unit: String
|
||||||
let viewModel: ViewModel
|
let viewModel: QuizViewModel
|
||||||
|
|
||||||
@Binding var value: Double
|
@Binding var value: Double
|
||||||
@Binding var submitted: Bool
|
@Binding var submitted: Bool
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import AudioToolbox
|
|||||||
|
|
||||||
struct QuizView: View {
|
struct QuizView: View {
|
||||||
|
|
||||||
@StateObject var viewModel = ViewModel()
|
@StateObject var quizViewModel = QuizViewModel()
|
||||||
@AppStorage("globalScore") var score: Int = 0
|
@AppStorage("globalScore") var score: Int = 0
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
@@ -19,29 +19,29 @@ struct QuizView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
if viewModel.isQuizFinished {
|
if quizViewModel.isQuizFinished {
|
||||||
QuizFinishedView(
|
QuizFinishedView(
|
||||||
score: viewModel.score,
|
score: quizViewModel.score,
|
||||||
total: viewModel.questions.count,
|
total: quizViewModel.questions.count,
|
||||||
isNewHighscore: viewModel.isNewHighscore,
|
isNewHighscore: quizViewModel.isNewHighscore,
|
||||||
onPlayAgain: { restartQuiz() },
|
onPlayAgain: { restartQuiz() },
|
||||||
onBackToCategories: { dismiss() }
|
onBackToCategories: { dismiss() }
|
||||||
)
|
)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
AudioServicesPlaySystemSound(1322)
|
AudioServicesPlaySystemSound(1322)
|
||||||
score += viewModel.score
|
score += quizViewModel.score
|
||||||
// Highscore prüfen/setzen
|
// Highscore prüfen/setzen
|
||||||
viewModel.isNewHighscore = viewModel.updateHighscoreIfNeeded()
|
quizViewModel.isNewHighscore = quizViewModel.updateHighscoreIfNeeded()
|
||||||
}
|
}
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
viewModel.isQuizFinished = false
|
quizViewModel.isQuizFinished = false
|
||||||
}
|
}
|
||||||
} else if let frage = viewModel.currentQuestion {
|
} else if let frage = quizViewModel.currentQuestion {
|
||||||
|
|
||||||
QuizHeader(
|
QuizHeader(
|
||||||
score: viewModel.score,
|
score: quizViewModel.score,
|
||||||
currentIndex: viewModel.currentQuestionIndex,
|
currentIndex: quizViewModel.currentQuestionIndex,
|
||||||
total: viewModel.questions.count,
|
total: quizViewModel.questions.count,
|
||||||
colorForStep: { idx in colorForAnswer(at: idx) }
|
colorForStep: { idx in colorForAnswer(at: idx) }
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,29 +56,29 @@ struct QuizView: View {
|
|||||||
let correctV = frage.correctValue {
|
let correctV = frage.correctValue {
|
||||||
// Estimation
|
// Estimation
|
||||||
EstimationQuestionView(
|
EstimationQuestionView(
|
||||||
questionID: viewModel.currentQuestionIndex, // <- neu
|
questionID: quizViewModel.currentQuestionIndex, // <- neu
|
||||||
minValue: minV,
|
minValue: minV,
|
||||||
maxValue: maxV,
|
maxValue: maxV,
|
||||||
correctValue: correctV,
|
correctValue: correctV,
|
||||||
unit: frage.unit ?? "",
|
unit: frage.unit ?? "",
|
||||||
viewModel: viewModel,
|
viewModel: quizViewModel,
|
||||||
value: $viewModel.estimationValue,
|
value: $quizViewModel.estimationValue,
|
||||||
submitted: $viewModel.estimationSubmitted,
|
submitted: $quizViewModel.estimationSubmitted,
|
||||||
gainedPoints: $viewModel.estimationPoints
|
gainedPoints: $quizViewModel.estimationPoints
|
||||||
) { gained in
|
) { gained in
|
||||||
viewModel.score += gained
|
quizViewModel.score += gained
|
||||||
viewModel.answeredCount += 1
|
quizViewModel.answeredCount += 1
|
||||||
viewModel.selectedAnswers[viewModel.currentQuestionIndex] = 0
|
quizViewModel.selectedAnswers[quizViewModel.currentQuestionIndex] = 0
|
||||||
viewModel.isAnswered = true
|
quizViewModel.isAnswered = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if viewModel.estimationSubmitted {
|
if quizViewModel.estimationSubmitted {
|
||||||
Button {
|
Button {
|
||||||
viewModel.loadNextQuestion()
|
quizViewModel.loadNextQuestion()
|
||||||
viewModel.estimationSubmitted = false
|
quizViewModel.estimationSubmitted = false
|
||||||
viewModel.isAnswered = false
|
quizViewModel.isAnswered = false
|
||||||
viewModel.selectedAnswerIndex = nil
|
quizViewModel.selectedAnswerIndex = nil
|
||||||
viewModel.estimationPoints = 0
|
quizViewModel.estimationPoints = 0
|
||||||
} label: {
|
} label: {
|
||||||
Text("Nächste Frage")
|
Text("Nächste Frage")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
@@ -96,22 +96,22 @@ struct QuizView: View {
|
|||||||
MultipleChoiceQuestionView(
|
MultipleChoiceQuestionView(
|
||||||
answers: frage.answers,
|
answers: frage.answers,
|
||||||
correctIndex: frage.correctAnswer,
|
correctIndex: frage.correctAnswer,
|
||||||
selectedIndex: $viewModel.selectedAnswerIndex,
|
selectedIndex: $quizViewModel.selectedAnswerIndex,
|
||||||
isAnswered: $viewModel.isAnswered,
|
isAnswered: $quizViewModel.isAnswered,
|
||||||
onAnswer: { index in
|
onAnswer: { index in
|
||||||
print("Selected:", index)
|
print("Selected:", index)
|
||||||
print("Correct:", frage.correctAnswer)
|
print("Correct:", frage.correctAnswer)
|
||||||
viewModel.incrementScore(selectedIndex: index)
|
quizViewModel.incrementScore(selectedIndex: index)
|
||||||
viewModel.answeredCount += 1
|
quizViewModel.answeredCount += 1
|
||||||
viewModel.selectedAnswers[viewModel.currentQuestionIndex] = index
|
quizViewModel.selectedAnswers[quizViewModel.currentQuestionIndex] = index
|
||||||
},
|
},
|
||||||
buttonColor: { idx, correct in
|
buttonColor: { idx, correct in
|
||||||
buttonColor(for: idx, correctIndex: correct)
|
buttonColor(for: idx, correctIndex: correct)
|
||||||
},
|
},
|
||||||
onNext: {
|
onNext: {
|
||||||
viewModel.loadNextQuestion()
|
quizViewModel.loadNextQuestion()
|
||||||
viewModel.selectedAnswerIndex = nil
|
quizViewModel.selectedAnswerIndex = nil
|
||||||
viewModel.isAnswered = false
|
quizViewModel.isAnswered = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -120,20 +120,20 @@ struct QuizView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
viewModel.loadQuestions(questions: questions, for: category)
|
quizViewModel.loadQuestions(questions: questions, for: category)
|
||||||
}
|
}
|
||||||
.navigationBarBackButtonHidden(!viewModel.isQuizFinished)
|
.navigationBarBackButtonHidden(!quizViewModel.isQuizFinished)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
if !viewModel.isQuizFinished {
|
if !quizViewModel.isQuizFinished {
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
Button("Abbrechen") {
|
Button("Abbrechen") {
|
||||||
viewModel.showExitAlert = true
|
quizViewModel.showExitAlert = true
|
||||||
}
|
}
|
||||||
.foregroundColor(.red)
|
.foregroundColor(.red)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.alert("Quiz verlassen?", isPresented: $viewModel.showExitAlert) {
|
.alert("Quiz verlassen?", isPresented: $quizViewModel.showExitAlert) {
|
||||||
Button("Quiz verlassen", role: .destructive) {
|
Button("Quiz verlassen", role: .destructive) {
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
@@ -145,11 +145,11 @@ struct QuizView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func buttonColor(for index: Int, correctIndex: Int) -> Color {
|
private func buttonColor(for index: Int, correctIndex: Int) -> Color {
|
||||||
guard viewModel.isAnswered else { return .blue }
|
guard quizViewModel.isAnswered else { return .blue }
|
||||||
|
|
||||||
if index == correctIndex {
|
if index == correctIndex {
|
||||||
return .green
|
return .green
|
||||||
} else if index == viewModel.selectedAnswerIndex {
|
} else if index == quizViewModel.selectedAnswerIndex {
|
||||||
return .red
|
return .red
|
||||||
} else {
|
} else {
|
||||||
return .gray
|
return .gray
|
||||||
@@ -157,34 +157,34 @@ struct QuizView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func restartQuiz() {
|
private func restartQuiz() {
|
||||||
viewModel.currentQuestionIndex = 0
|
quizViewModel.currentQuestionIndex = 0
|
||||||
viewModel.score = 0
|
quizViewModel.score = 0
|
||||||
viewModel.isQuizFinished = false
|
quizViewModel.isQuizFinished = false
|
||||||
viewModel.selectedAnswerIndex = nil
|
quizViewModel.selectedAnswerIndex = nil
|
||||||
viewModel.isAnswered = false
|
quizViewModel.isAnswered = false
|
||||||
viewModel.answeredCount = 0
|
quizViewModel.answeredCount = 0
|
||||||
viewModel.selectedAnswers = Array(repeating: nil, count: viewModel.questions.count)
|
quizViewModel.selectedAnswers = Array(repeating: nil, count: quizViewModel.questions.count)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func colorForAnswer(at index: Int) -> Color {
|
private func colorForAnswer(at index: Int) -> Color {
|
||||||
if index == viewModel.currentQuestionIndex,
|
if index == quizViewModel.currentQuestionIndex,
|
||||||
viewModel.selectedAnswers[index] == nil {
|
quizViewModel.selectedAnswers[index] == nil {
|
||||||
return Color.blue // aktuelle Frage
|
return Color.blue // aktuelle Frage
|
||||||
}
|
}
|
||||||
|
|
||||||
guard index < viewModel.selectedAnswers.count,
|
guard index < quizViewModel.selectedAnswers.count,
|
||||||
index < viewModel.questions.count else {
|
index < quizViewModel.questions.count else {
|
||||||
return Color.gray.opacity(0.3) // unbeantwortet
|
return Color.gray.opacity(0.3) // unbeantwortet
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüfen ob die Frage beantwortet wurde
|
// Prüfen ob die Frage beantwortet wurde
|
||||||
let question = viewModel.questions[index]
|
let question = quizViewModel.questions[index]
|
||||||
if question.isEstimation {
|
if question.isEstimation {
|
||||||
// Bei Estimation-Fragen: Grün wenn beantwortet
|
// Bei Estimation-Fragen: Grün wenn beantwortet
|
||||||
return viewModel.selectedAnswers[index] != nil ? .green : Color.gray.opacity(0.3)
|
return quizViewModel.selectedAnswers[index] != nil ? .green : Color.gray.opacity(0.3)
|
||||||
} else {
|
} else {
|
||||||
// Bei Multiple-Choice: Grün wenn richtig, rot wenn falsch
|
// Bei Multiple-Choice: Grün wenn richtig, rot wenn falsch
|
||||||
if let selected = viewModel.selectedAnswers[index] {
|
if let selected = quizViewModel.selectedAnswers[index] {
|
||||||
let correct = question.correctAnswer
|
let correct = question.correctAnswer
|
||||||
return selected == correct ? .green : .red
|
return selected == correct ? .green : .red
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user