diff --git a/Rosetta/Features/Chats/ChatDetail/ListView/RosettaMessageListController.swift b/Rosetta/Features/Chats/ChatDetail/ListView/RosettaMessageListController.swift index 7a7ae4f..57f13f1 100644 --- a/Rosetta/Features/Chats/ChatDetail/ListView/RosettaMessageListController.swift +++ b/Rosetta/Features/Chats/ChatDetail/ListView/RosettaMessageListController.swift @@ -101,6 +101,45 @@ final class RosettaMessageListController: UIViewController { listView.onScroll = { [weak self] _, _ in // TODO: scroll-to-bottom button visibility } + + // Keyboard tracking + NotificationCenter.default.addObserver( + self, selector: #selector(keyboardWillShow(_:)), + name: UIResponder.keyboardWillShowNotification, object: nil + ) + NotificationCenter.default.addObserver( + self, selector: #selector(keyboardWillHide(_:)), + name: UIResponder.keyboardWillHideNotification, object: nil + ) + } + + // MARK: - Keyboard + + @objc private func keyboardWillShow(_ notification: Notification) { + guard let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect, + let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double, + let curveRaw = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt + else { return } + + let keyboardHeight = frame.height + let curve = UIView.AnimationOptions(rawValue: curveRaw << 16) + + UIView.animate(withDuration: duration, delay: 0, options: curve) { + self.listView.contentInsets.bottom = keyboardHeight + } + } + + @objc private func keyboardWillHide(_ notification: Notification) { + guard let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double, + let curveRaw = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt + else { return } + + let curve = UIView.AnimationOptions(rawValue: curveRaw << 16) + + UIView.animate(withDuration: duration, delay: 0, options: curve) { + self.listView.contentInsets.bottom = 0 + } + onKeyboardDidHide?() } /// Setup composer view (called externally after init).