diff --git a/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController+Keyboard.swift b/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController+Keyboard.swift new file mode 100644 index 0000000000..bb26c8a6d2 --- /dev/null +++ b/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController+Keyboard.swift @@ -0,0 +1,43 @@ +// +// IntelligentsChatController+Keyboard.swift +// Intelligents +// +// Created by 秋星桥 on 2024/12/6. +// + +import UIKit + +extension IntelligentsChatController { + @objc func keyboardWillAppear(_ notification: Notification) { + let info = notification.userInfo ?? [:] + let keyboardHeight = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)? + .cgRectValue + .height ?? 0 + inputBoxKeyboardAdapterHeightConstraint.constant = keyboardHeight + view.setNeedsUpdateConstraints() + animateWithKeyboard(userInfo: info) + } + + @objc func keyboardWillDisappear(_ notification: Notification) { + let info = notification.userInfo ?? [:] + inputBoxKeyboardAdapterHeightConstraint.constant = 0 + view.setNeedsUpdateConstraints() + animateWithKeyboard(userInfo: info) + } + + private func animateWithKeyboard(userInfo info: [AnyHashable: Any]) { + let keyboardAnimationDuration = (info[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)? + .doubleValue ?? 0 + let keyboardAnimationCurve = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)? + .uintValue ?? 0 + UIView.animate( + withDuration: keyboardAnimationDuration, + delay: 0, + options: UIView.AnimationOptions(rawValue: keyboardAnimationCurve), + animations: { + self.view.layoutIfNeeded() + }, + completion: nil + ) + } +} diff --git a/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController.swift b/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController.swift index b316e38962..54f5c35721 100644 --- a/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController.swift +++ b/packages/frontend/apps/ios/App/App/Packages/Intelligents/Sources/Intelligents/IntelligentsChatController/IntelligentsChatController.swift @@ -9,9 +9,12 @@ import UIKit public class IntelligentsChatController: UIViewController { let header = Header() + let inputBoxKeyboardAdapter = UIView() let inputBox = InputBox() let tableView = ChatTableView() + var inputBoxKeyboardAdapterHeightConstraint = NSLayoutConstraint() + override public var title: String? { set { super.title = newValue @@ -25,6 +28,19 @@ public class IntelligentsChatController: UIViewController { public init() { super.init(nibName: nil, bundle: nil) title = "Chat with AI".localized() + + NotificationCenter.default.addObserver( + self, + selector: #selector(keyboardWillDisappear), + name: UIResponder.keyboardWillHideNotification, + object: nil + ) + NotificationCenter.default.addObserver( + self, + selector: #selector(keyboardWillAppear), + name: UIResponder.keyboardWillShowNotification, + object: nil + ) } @available(*, unavailable) @@ -32,6 +48,10 @@ public class IntelligentsChatController: UIViewController { fatalError() } + deinit { + NotificationCenter.default.removeObserver(self) + } + override public func viewDidLoad() { super.viewDidLoad() assert(navigationController != nil) @@ -51,12 +71,23 @@ public class IntelligentsChatController: UIViewController { header.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 44), ].forEach { $0.isActive = true } + view.addSubview(inputBoxKeyboardAdapter) + inputBoxKeyboardAdapter.translatesAutoresizingMaskIntoConstraints = false + [ + inputBoxKeyboardAdapter.leadingAnchor.constraint(equalTo: view.leadingAnchor), + inputBoxKeyboardAdapter.trailingAnchor.constraint(equalTo: view.trailingAnchor), + inputBoxKeyboardAdapter.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + ].forEach { $0.isActive = true } + inputBoxKeyboardAdapterHeightConstraint = inputBoxKeyboardAdapter.heightAnchor.constraint(equalToConstant: 0) + inputBoxKeyboardAdapterHeightConstraint.isActive = true + inputBoxKeyboardAdapter.backgroundColor = inputBox.backgroundView.backgroundColor + view.addSubview(inputBox) inputBox.translatesAutoresizingMaskIntoConstraints = false [ inputBox.leadingAnchor.constraint(equalTo: view.leadingAnchor), inputBox.trailingAnchor.constraint(equalTo: view.trailingAnchor), - inputBox.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + inputBox.bottomAnchor.constraint(equalTo: inputBoxKeyboardAdapter.topAnchor), ].forEach { $0.isActive = true } view.addSubview(tableView)