Compare commits

...

5 Commits

Author SHA1 Message Date
fish 486fda8fc6 确认按钮仅在学习模式显示
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-20 22:06:13 +08:00
fish e890350f9a 确认后按钮立即禁用,刷新后重新启用
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-20 22:02:51 +08:00
fish 794608d69c 学习模式确认后保持键盘不消失
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-20 22:01:40 +08:00
fish 797b841f07 学习模式取消自动检查,改为确认按钮手动提交
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-20 22:00:24 +08:00
fish 28b61d20f1 调整确认按钮尺寸、圆角、键盘间距,支持横竖屏适配
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-20 21:58:09 +08:00
2 changed files with 30 additions and 8 deletions
@@ -222,10 +222,12 @@ final class QuizViewController: UIViewController {
if config.isStudyMode { if config.isStudyMode {
nextButton.isHidden = true nextButton.isHidden = true
spellingView.onChange = { [weak self] in spellingView.onChange = { [weak self] in
guard let self, spellingView.isComplete else { return } guard let self else { return }
submitSpelling(spellingView.typedWord(), for: question) spellingView.confirmButton?.isEnabled = spellingView.isComplete
} }
spellingView.confirmButton?.isEnabled = false
} else { } else {
spellingView.hideAccessoryView()
spellingView.onChange = { [weak self] in spellingView.onChange = { [weak self] in
guard let self else { return } guard let self else { return }
nextButton.isEnabled = spellingView.isComplete nextButton.isEnabled = spellingView.isComplete
@@ -235,7 +237,9 @@ final class QuizViewController: UIViewController {
nextButton.isHidden = false nextButton.isHidden = false
} }
spellingView.onSubmit = { [weak self] in spellingView.onSubmit = { [weak self] in
self?.primaryButtonTapped() guard let self else { return }
spellingView.confirmButton?.isEnabled = false
primaryButtonTapped()
} }
spellingView.activate() spellingView.activate()
} else if isDictation { } else if isDictation {
@@ -358,7 +362,11 @@ final class QuizViewController: UIViewController {
wrongWords.append(question.word) wrongWords.append(question.word)
} }
correct ? Haptics.correct() : Haptics.wrong() correct ? Haptics.correct() : Haptics.wrong()
if config.isStudyMode {
spellingView.freezeInput()
} else {
spellingView.deactivate() spellingView.deactivate()
}
spellingView.showResultState(correct: correct) spellingView.showResultState(correct: correct)
showResult(correct, for: question) showResult(correct, for: question)
} }
@@ -3,6 +3,7 @@ import UIKit
final class SpellingInputView: UIView, UITextFieldDelegate { final class SpellingInputView: UIView, UITextFieldDelegate {
var onChange: (() -> Void)? var onChange: (() -> Void)?
var onSubmit: (() -> Void)? var onSubmit: (() -> Void)?
private(set) var confirmButton: UIButton?
private let hiddenField = UITextField() private let hiddenField = UITextField()
private let stack = UIStackView() private let stack = UIStackView()
@@ -58,12 +59,14 @@ final class SpellingInputView: UIView, UITextFieldDelegate {
addSubview(hiddenField) addSubview(hiddenField)
let accessory = UIView() let accessory = UIView()
accessory.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 52) accessory.frame = CGRect(x: 0, y: 0, width: 0, height: 74)
accessory.autoresizingMask = .flexibleWidth
accessory.backgroundColor = .clear accessory.backgroundColor = .clear
var glassConfig = UIButton.Configuration.glass() var glassConfig = UIButton.Configuration.glass()
glassConfig.title = "确认" glassConfig.title = "确认"
glassConfig.cornerStyle = .fixed glassConfig.cornerStyle = .fixed
glassConfig.background.cornerRadius = 25
glassConfig.baseForegroundColor = .label glassConfig.baseForegroundColor = .label
glassConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in glassConfig.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
var outgoing = incoming var outgoing = incoming
@@ -71,6 +74,7 @@ final class SpellingInputView: UIView, UITextFieldDelegate {
return outgoing return outgoing
} }
let glassButton = UIButton(configuration: glassConfig) let glassButton = UIButton(configuration: glassConfig)
confirmButton = glassButton
glassButton.addAction(UIAction { [weak self] _ in glassButton.addAction(UIAction { [weak self] _ in
self?.onSubmit?() self?.onSubmit?()
}, for: .touchUpInside) }, for: .touchUpInside)
@@ -78,9 +82,9 @@ final class SpellingInputView: UIView, UITextFieldDelegate {
accessory.addSubview(glassButton) accessory.addSubview(glassButton)
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
glassButton.trailingAnchor.constraint(equalTo: accessory.trailingAnchor, constant: -15), glassButton.trailingAnchor.constraint(equalTo: accessory.trailingAnchor, constant: -15),
glassButton.centerYAnchor.constraint(equalTo: accessory.centerYAnchor), glassButton.topAnchor.constraint(equalTo: accessory.topAnchor, constant: 12),
glassButton.widthAnchor.constraint(equalToConstant: 60), glassButton.widthAnchor.constraint(equalToConstant: 80),
glassButton.heightAnchor.constraint(equalToConstant: 44) glassButton.heightAnchor.constraint(equalToConstant: 50)
]) ])
hiddenField.inputAccessoryView = accessory hiddenField.inputAccessoryView = accessory
@@ -118,6 +122,16 @@ final class SpellingInputView: UIView, UITextFieldDelegate {
refreshBoxes() refreshBoxes()
} }
func freezeInput() {
inputEnabled = false
refreshBoxes()
}
func hideAccessoryView() {
confirmButton?.isHidden = true
hiddenField.inputAccessoryView = nil
}
func showResultState(correct: Bool) { func showResultState(correct: Bool) {
let color = correct ? Theme.Color.correct : Theme.Color.wrong let color = correct ? Theme.Color.correct : Theme.Color.wrong
for position in blankPositions { for position in blankPositions {