From 0df02d487e6dcb516030e680b04e6982d25f5e0c Mon Sep 17 00:00:00 2001 From: fish Date: Tue, 21 Jul 2026 21:13:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=9D=E7=95=99=E6=8B=BC=E5=86=99=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E6=8C=89=E9=92=AE=EF=BC=8C=E5=90=8C=E6=97=B6=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E9=94=AE=E7=9B=98=E5=AE=8C=E6=88=90=E9=94=AE=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- .../Views/QuizViewController.swift | 7 ++++ .../Views/SpellingInputView.swift | 36 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/LearnEnglish/LearnEnglish/Views/QuizViewController.swift b/LearnEnglish/LearnEnglish/Views/QuizViewController.swift index 341de60..1d96773 100644 --- a/LearnEnglish/LearnEnglish/Views/QuizViewController.swift +++ b/LearnEnglish/LearnEnglish/Views/QuizViewController.swift @@ -221,7 +221,13 @@ final class QuizViewController: UIViewController { spellingView.configure(blankedWord: question.blankedWord, blankPositions: question.blankPositions) if config.isStudyMode { nextButton.isHidden = true + spellingView.onChange = { [weak self] in + guard let self else { return } + spellingView.confirmButton?.isEnabled = spellingView.isComplete + } + spellingView.confirmButton?.isEnabled = false } else { + spellingView.hideAccessoryView() spellingView.onChange = { [weak self] in guard let self else { return } nextButton.isEnabled = spellingView.isComplete @@ -232,6 +238,7 @@ final class QuizViewController: UIViewController { } spellingView.onSubmit = { [weak self] in guard let self else { return } + spellingView.confirmButton?.isEnabled = false primaryButtonTapped() } spellingView.activate() diff --git a/LearnEnglish/LearnEnglish/Views/SpellingInputView.swift b/LearnEnglish/LearnEnglish/Views/SpellingInputView.swift index f0965e1..e3dd901 100644 --- a/LearnEnglish/LearnEnglish/Views/SpellingInputView.swift +++ b/LearnEnglish/LearnEnglish/Views/SpellingInputView.swift @@ -3,6 +3,7 @@ import UIKit final class SpellingInputView: UIView, UITextFieldDelegate { var onChange: (() -> Void)? var onSubmit: (() -> Void)? + private(set) var confirmButton: UIButton? private let hiddenField = UITextField() private let stack = UIStackView() @@ -58,6 +59,36 @@ final class SpellingInputView: UIView, UITextFieldDelegate { hiddenField.frame = .zero addSubview(hiddenField) + let accessory = UIView() + accessory.frame = CGRect(x: 0, y: 0, width: 0, height: 74) + accessory.autoresizingMask = .flexibleWidth + accessory.backgroundColor = .clear + + var glassConfig = UIButton.Configuration.glass() + glassConfig.title = "确认" + glassConfig.cornerStyle = .fixed + glassConfig.background.cornerRadius = 25 + glassConfig.baseForegroundColor = .label + glassConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in + var outgoing = incoming + outgoing.font = .systemFont(ofSize: 16, weight: .semibold) + return outgoing + } + let glassButton = UIButton(configuration: glassConfig) + confirmButton = glassButton + glassButton.addAction(UIAction { [weak self] _ in + self?.onSubmit?() + }, for: .touchUpInside) + glassButton.translatesAutoresizingMaskIntoConstraints = false + accessory.addSubview(glassButton) + NSLayoutConstraint.activate([ + glassButton.trailingAnchor.constraint(equalTo: accessory.trailingAnchor, constant: -15), + glassButton.topAnchor.constraint(equalTo: accessory.topAnchor, constant: 12), + glassButton.widthAnchor.constraint(equalToConstant: 80), + glassButton.heightAnchor.constraint(equalToConstant: 50) + ]) + hiddenField.inputAccessoryView = accessory + addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(reactivate))) } @@ -97,6 +128,11 @@ final class SpellingInputView: UIView, UITextFieldDelegate { refreshBoxes() } + func hideAccessoryView() { + confirmButton?.isHidden = true + hiddenField.inputAccessoryView = nil + } + func showResultState(correct: Bool) { let color = correct ? Theme.Color.correct : Theme.Color.wrong for position in blankPositions {