diff --git a/Tusker/Screens/Compose/ComposeContentWarningTextField.swift b/Tusker/Screens/Compose/ComposeContentWarningTextField.swift index befd6ae0..309864b6 100644 --- a/Tusker/Screens/Compose/ComposeContentWarningTextField.swift +++ b/Tusker/Screens/Compose/ComposeContentWarningTextField.swift @@ -32,7 +32,11 @@ struct ComposeContentWarningTextField: UIViewRepresentable { } func updateUIView(_ uiView: UITextField, context: Context) { - uiView.text = text + if context.coordinator.skipSettingTextOnNextUpdate { + context.coordinator.skipSettingTextOnNextUpdate = false + } else { + uiView.text = text + } } func makeCoordinator() -> Coordinator { @@ -44,6 +48,8 @@ struct ComposeContentWarningTextField: UIViewRepresentable { var text: Binding! var uiState: ComposeUIState! + var skipSettingTextOnNextUpdate = false + @objc func didChange(_ textField: UITextField) { text.wrappedValue = textField.text ?? "" } @@ -57,6 +63,12 @@ struct ComposeContentWarningTextField: UIViewRepresentable { updateAutocompleteState(textField: textField) } + func textFieldDidChangeSelection(_ textField: UITextField) { + // see MainComposeTextView.Coordinator.textViewDidChangeSelection(_:) + skipSettingTextOnNextUpdate = true + self.updateAutocompleteState(textField: textField) + } + func autocomplete(with string: String) { guard let textField = textField, let text = textField.text, diff --git a/Tusker/Screens/Compose/MainComposeTextView.swift b/Tusker/Screens/Compose/MainComposeTextView.swift index c356bb2a..1582c735 100644 --- a/Tusker/Screens/Compose/MainComposeTextView.swift +++ b/Tusker/Screens/Compose/MainComposeTextView.swift @@ -135,7 +135,11 @@ struct MainComposeWrappedTextView: UIViewRepresentable { } func updateUIView(_ uiView: UITextView, context: Context) { - uiView.text = text + if context.coordinator.skipSettingTextOnNextUpdate { + context.coordinator.skipSettingTextOnNextUpdate = false + } else { + uiView.text = text + } if let visibilityButton = visibilityButton { visibilityButton.image = UIImage(systemName: visibility.imageName) @@ -199,6 +203,8 @@ struct MainComposeWrappedTextView: UIViewRepresentable { var uiState: ComposeUIState var caretScrollPositionAnimator: UIViewPropertyAnimator? + var skipSettingTextOnNextUpdate = false + init(text: Binding, uiState: ComposeUIState, didChange: @escaping (UITextView) -> Void) { self.text = text self.didChange = didChange @@ -258,6 +264,14 @@ struct MainComposeWrappedTextView: UIViewRepresentable { updateAutocompleteState() } + func textViewDidChangeSelection(_ textView: UITextView) { + // Setting the text view's text causes it to move the cursor to the end (though only + // when the text contains an emoji :/), so skip setting the text on the next SwiftUI update + // that's triggered by setting the autocomplete state. + skipSettingTextOnNextUpdate = true + self.updateAutocompleteState() + } + func autocomplete(with string: String) { guard let textView = textView, let text = textView.text,