signalapp / Signal-iOS

A private messenger for iOS.
https://signal.org
GNU Affero General Public License v3.0
10.6k stars 2.95k forks source link

Keyboard does not reset when sending message #5731

Closed axelvugts closed 3 weeks ago

axelvugts commented 5 months ago

When sending a message in a chat, the state of the native iOS keyboard is not reset. So if you were writing in all caps, this will continue in the next message.

SaifCoder commented 5 months ago

This is not a issue. It's a feature of iOS. For reference please check Message app and WhatsApp.

axelvugts commented 5 months ago

Thanks for your reply! I see that I added the wrong example, and you're right that Messages does not reset the keyboard after typing in caps. However, when ending a sentence with e.g. an exclamation mark (!), Messages and WhatsApp do reset the keyboard to the main page while Signal does not.

pkillian commented 4 months ago

I was able to reproduce this behavior, but I'm not convinced what Messages does is best. Here are some findings:

In ConversationViewController+ConversationInputToolbarDelegate::tryToSendTextMessage(_ messageBody, updateKeyboardState, untrustedThreshold), it seems like the updateKeyboardState parameter is never used: https://github.com/signalapp/Signal-iOS/blob/75b1b04c05abf1e19c7c04a570236cb0399fcec6/Signal/src/ViewControllers/ConversationView/ConversationViewController%2BConversationInputToolbarDelegate.swift#L69-L199

I was investigating adding ConversationInputToolbar.restoreKeyboardState() and calling it in the function above right after kicking off the write to database storage:

    // Update keyboard state back to default
    if updateKeyboardState {
        inputToolbar.restoreKeyboardState()
    }

The tricky part here is how to correctly get the keyboard back to its default state. Calling inputTextView.reloadInputViews() doesn't work unless the input views have been modified, like by setting a new keyboardType value for example. A slightly messy implementation would be to alternate between the default keyboard type, and asciiCapable like so:

    func restoreKeyboardState() {
        // Alternate between .default and .asciiCapable to force input views to reload
        if inputTextView.keyboardType == .default {
            inputTextView.keyboardType = .asciiCapable
        } else {
            inputTextView.keyboardType = .default
        }

        inputTextView.reloadInputViews()
    }

The more "correct" implementation would be for the inputTextView to resign first responder, then immediately become first responder again. This causes glitchy UI updates, even when disabling animations on UIView first.

stale[bot] commented 4 weeks ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 3 weeks ago

This issue has been closed due to inactivity.