diff --git a/Tusker/Screens/Compose/ComposeTextView.swift b/Tusker/Screens/Compose/ComposeTextView.swift index 48d1a374..dd606240 100644 --- a/Tusker/Screens/Compose/ComposeTextView.swift +++ b/Tusker/Screens/Compose/ComposeTextView.swift @@ -82,6 +82,7 @@ struct WrappedTextView: UIViewRepresentable { func updateUIView(_ uiView: UITextView, context: Context) { uiView.text = text + context.coordinator.textView = uiView context.coordinator.text = $text context.coordinator.didChange = textDidChange // wait until the next runloop iteration so that SwiftUI view updates have finished and @@ -96,6 +97,7 @@ struct WrappedTextView: UIViewRepresentable { } class Coordinator: NSObject, UITextViewDelegate, ComposeTextViewCaretScrolling { + weak var textView: UITextView? var text: Binding var didChange: ((UITextView) -> Void)? var caretScrollPositionAnimator: UIViewPropertyAnimator? @@ -103,6 +105,16 @@ struct WrappedTextView: UIViewRepresentable { init(text: Binding, didChange: ((UITextView) -> Void)?) { self.text = text self.didChange = didChange + + super.init() + + NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: UIResponder.keyboardDidShowNotification, object: nil) + } + + @objc private func keyboardDidShow() { + guard let textView, + textView.isFirstResponder else { return } + ensureCursorVisible(textView: textView) } func textViewDidChange(_ textView: UITextView) { diff --git a/Tusker/Screens/Compose/ComposeTextViewCaretScrolling.swift b/Tusker/Screens/Compose/ComposeTextViewCaretScrolling.swift index 565d2f5a..b2a68561 100644 --- a/Tusker/Screens/Compose/ComposeTextViewCaretScrolling.swift +++ b/Tusker/Screens/Compose/ComposeTextViewCaretScrolling.swift @@ -37,7 +37,7 @@ extension ComposeTextViewCaretScrolling { rectToMakeVisible.origin.y -= cursorRect.height rectToMakeVisible.size.height *= 3 - let animator = UIViewPropertyAnimator(duration: 0.1, curve: .linear) { + let animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeInOut) { scrollView.scrollRectToVisible(rectToMakeVisible, animated: false) } self.caretScrollPositionAnimator = animator diff --git a/Tusker/Screens/Compose/MainComposeTextView.swift b/Tusker/Screens/Compose/MainComposeTextView.swift index 40ace2ba..4a6bb4fd 100644 --- a/Tusker/Screens/Compose/MainComposeTextView.swift +++ b/Tusker/Screens/Compose/MainComposeTextView.swift @@ -168,6 +168,16 @@ struct MainComposeWrappedTextView: UIViewRepresentable { self.text = text self.didChange = didChange self.uiState = uiState + + super.init() + + NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: UIResponder.keyboardDidShowNotification, object: nil) + } + + @objc private func keyboardDidShow() { + guard let textView, + textView.isFirstResponder else { return } + ensureCursorVisible(textView: textView) } func textViewDidChange(_ textView: UITextView) {