Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Chatto/Source/ChatController/BaseChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,21 @@ open class BaseChatViewController: UIViewController,
self.keyboardTracker = KeyboardTracker(viewController: self, inputBarContainer: self.inputBarContainer, heightBlock: heightBlock, notificationCenter: self.notificationCenter)

(self.view as? BaseChatViewControllerViewProtocol)?.bmaInputAccessoryView = self.keyboardTracker?.trackingView

if #available(iOS 26, *) {
notificationCenter.removeObserver(self.keyboardTracker!)
inputContainerBottomConstraint.isActive = false
inputBarContainer.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
inputBarContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
inputBarContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
inputBarContainer.bottomAnchor.constraint(
equalTo: view.keyboardLayoutGuide.topAnchor
)
])
view.keyboardLayoutGuide.followsUndockedKeyboard = true
}
}

var notificationCenter = NotificationCenter.default
Expand Down
23 changes: 21 additions & 2 deletions ChattoAdditions/Source/Input/ChatInputBarPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,23 @@ public class BasicChatInputBarPresenter: NSObject, ChatInputBarPresenter {
private var lastKnownKeyboardHeight: CGFloat?
private var allowListenToChangeFrameEvents = true

/// iOS 26 adds a grabber/separator above custom input views.
/// No public API exists to query this value.
private var inputViewGrabberHeight: CGFloat {
if #available(iOS 26, *) {
return 17.0
}
return 0
}

// MARK: Input View

private weak var currentInputView: InputContainerView?

private func updateHeight(for inputView: InputContainerView) {
inputView.contentHeight = {
if let keyboardHeight = self.lastKnownKeyboardHeight, keyboardHeight > 0 {
return keyboardHeight
return keyboardHeight - self.inputViewGrabberHeight
} else {
if UIScreen.main.portraitOrientation {
return UIScreen.main.defaultPortraitKeyboardHeight
Expand All @@ -135,7 +144,17 @@ public class BasicChatInputBarPresenter: NSObject, ChatInputBarPresenter {
guard self.focusedItem != nil else { return }
guard let value = (notification as NSNotification).userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
guard value.cgRectValue.height > 0 else { return }
self.lastKnownKeyboardHeight = value.cgRectValue.height - self.chatInputBar.bounds.height
var keyboardHeight: CGFloat
if #available(iOS 26, *) {
// iOS 26 no longer includes the input accessory view (chat bar)
// in the reported keyboard frame, so we skip the subtraction.
// Note that for custom intput views, the grabber height is still included in the keyboard frame,
// so we have to subtract it out.
keyboardHeight = value.cgRectValue.height
} else {
keyboardHeight = value.cgRectValue.height - self.chatInputBar.bounds.height
}
self.lastKnownKeyboardHeight = keyboardHeight
}

@objc
Expand Down