Guard quiz Next/Previous against double taps

A rapid second tap on Next (easy to trigger with Apple Pencil) called
advance() twice before the view tree re-rendered, skipping a card.
Share a single isAdvancing flag between advance() and a new goBack()
helper, disable both buttons while the flag is set, and clear it after
350 ms so queued Pencil events are absorbed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-11 18:52:08 -05:00
parent 4e874f60d7
commit 3b8a8a7f1a

View File

@@ -18,6 +18,7 @@ struct CourseQuizView: View {
@State private var currentIndex = 0
@State private var correctCount = 0
@State private var missedItems: [MissedCourseItem] = []
@State private var isAdvancing = false
// Per-question state
@State private var userAnswer = ""
@@ -311,16 +312,13 @@ struct CourseQuizView: View {
// Nav arrows
HStack {
Button {
guard currentIndex > 0 else { return }
currentIndex -= 1
resetQuestion()
prepareQuestion()
goBack()
} label: {
Label("Previous", systemImage: "chevron.left")
.font(.subheadline)
}
.tint(.secondary)
.disabled(currentIndex == 0)
.disabled(currentIndex == 0 || isAdvancing)
Spacer()
@@ -332,6 +330,7 @@ struct CourseQuizView: View {
.labelStyle(.titleAndIcon)
}
.tint(.blue)
.disabled(isAdvancing)
}
.padding(.horizontal)
}
@@ -498,6 +497,8 @@ struct CourseQuizView: View {
}
private func advance() {
guard !isAdvancing else { return }
isAdvancing = true
currentIndex += 1
if isComplete {
saveResult()
@@ -505,6 +506,20 @@ struct CourseQuizView: View {
resetQuestion()
prepareQuestion()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
isAdvancing = false
}
}
private func goBack() {
guard !isAdvancing, currentIndex > 0 else { return }
isAdvancing = true
currentIndex -= 1
resetQuestion()
prepareQuestion()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
isAdvancing = false
}
}
private func saveResult() {