完善任务流程、键盘适配与页面交互

This commit is contained in:
2026-07-10 15:56:15 +08:00
parent f88a85a807
commit ab5220e460
189 changed files with 16779 additions and 1038 deletions

View File

@ -6,7 +6,7 @@
import SnapKit
import UIKit
///
/// `IQKeyboardManager`
class KeyboardAvoidingDialogView: UIView {
///
@ -18,8 +18,6 @@ class KeyboardAvoidingDialogView: UIView {
///
var keyboardAvoidingMinimumSpacing: CGFloat = AppSpacing.md
private var keyboardObservers: [NSObjectProtocol] = []
override init(frame: CGRect) {
super.init(frame: frame)
}
@ -29,77 +27,4 @@ class KeyboardAvoidingDialogView: UIView {
fatalError("init(coder:) has not been implemented")
}
deinit {
unregisterKeyboardObservers()
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview == nil {
unregisterKeyboardObservers()
} else {
registerKeyboardObservers()
}
}
private func registerKeyboardObservers() {
unregisterKeyboardObservers()
let center = NotificationCenter.default
keyboardObservers = [
center.addObserver(
forName: UIResponder.keyboardWillChangeFrameNotification,
object: nil,
queue: .main
) { [weak self] notification in
self?.handleKeyboardNotification(notification)
},
center.addObserver(
forName: UIResponder.keyboardWillHideNotification,
object: nil,
queue: .main
) { [weak self] notification in
self?.handleKeyboardNotification(notification)
}
]
}
private func unregisterKeyboardObservers() {
keyboardObservers.forEach(NotificationCenter.default.removeObserver)
keyboardObservers.removeAll()
}
private func handleKeyboardNotification(_ notification: Notification) {
layoutIfNeeded()
guard let userInfo = notification.userInfo else { return }
let duration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.25
let curveRaw = (userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue
?? UInt(UIView.AnimationCurve.easeInOut.rawValue)
let options = UIView.AnimationOptions(rawValue: curveRaw << 16)
keyboardAvoidingCenterYConstraint?.update(offset: keyboardAvoidanceOffset(from: userInfo))
UIView.animate(withDuration: duration, delay: 0, options: options) {
self.layoutIfNeeded()
}
}
private func keyboardAvoidanceOffset(from userInfo: [AnyHashable: Any]) -> CGFloat {
guard
let contentView = keyboardAvoidingContentView,
let keyboardFrameValue = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue
else {
return 0
}
let keyboardFrame = convert(keyboardFrameValue.cgRectValue, from: nil)
guard keyboardFrame.minY < bounds.height else { return 0 }
let contentHeight = contentView.bounds.height
let baseMinY = bounds.midY - contentHeight / 2
let baseMaxY = bounds.midY + contentHeight / 2
let desiredBottom = keyboardFrame.minY - keyboardAvoidingMinimumSpacing
let neededShift = max(0, baseMaxY - desiredBottom)
let maxShift = max(0, baseMinY - keyboardAvoidingMinimumSpacing)
return -min(neededShift, maxShift)
}
}