4
votes

I've UITextView, next to it and separate from text view is a send button. After user types text in text view and taps send button, keyboard hides. I don't want to hide keyboard after user taps on send button. How do I achieve this?

Updating question to provide more details. 1) Send Button is a separate UIButton. 2) I don't have any resignFirstResponder being called exclusively in the code. 3) After send button is clicked I've following code which shows/hides keyboard.

override func viewDidLoad() {
    super.viewDidLoad()
    // Setup keyboard event
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
}

// Setup keyboard event
@objc func keyboardWillShow(notification:NSNotification){
    print("keyboardWillShow")
    var userInfo = notification.userInfo!
    var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    keyboardFrame = self.view.convert(keyboardFrame, from: nil)

    var contentInset:UIEdgeInsets = self.scrollView.contentInset
    contentInset.bottom = keyboardFrame.size.height
    scrollView.contentInset = contentInset
}

@objc func keyboardWillHide(notification:NSNotification){
    print("keyboardWillHide")
    let contentInset:UIEdgeInsets = UIEdgeInsets.zero
    scrollView.contentInset = contentInset
}

Send button clicked code

@IBAction func sendButtonClicked(_ sender: UIButton) {

    // Disable textview and send button while message is being sent
    messageTextView.isEditable = false
    sendButton.isEnabled = false

    fetchSendMessage( ) { (result, error) in
        if error != nil {
            ShowDialog.showDialog(title: nil, message: (error?.localizedDescription)!, viewController: self)
        } else {
            if (result?.success)! {
                self.arry = (result?.data)!

                self.fetchMessages(page: 1, completed: {
                    self.insertNewMessage(sentMessage)
                })

                // Clear the message & Enable textview and send button
                self.messageTextView.isEditable = true
                self.messageTextView.text = "Type Message"
                self.messageTextView.textColor = UIColor.greyColour
                self.sendButton.isEnabled = true
                self.messageTextView.endEditing(true)
            } else {
                ShowDialog.showDialog(title: "Message not sent", message: (result?.errors![0].message)!, viewController: self)

                // Retain typed message
                // Enable textview and send button
                self.messageTextView.isEditable = true
                self.sendButton.isEnabled = true
            }
        }
    }
}
2
Great question. Could you please, however, provide your current code and any attempts you've made.Callum
When you set textView.returnKeyType = .send, the Send key still inserts a newline into the text view and does not dismiss the keyboard. Can you detail your view setup?Code Different
Find the place where : textView.resignFirstResponder(). If textView won't resign, the keyboard should not hide.E.Coms
I can't find any resignFirstResponder in my code.Dan
Sorry, it's not the return key thingy. I've a separate Send button (UIButton).Dan

2 Answers

1
votes

When we are trying to disable UITextView's editable option or UserInteraction, automatically keyboard get hides.

Instead of doing this,

messageTextView.isEditable = false

Way 2:

You can create UIView and addSubView to UIWindow, that will not hide keyboard and also user cannot type.

var overView : UIView? // GLOBAL DECLARATION

func addOverView() { // CALL THIS WHEN SEND BUTTON CLICKED

   let window = UIApplication.shared.keyWindow!
   overView = UIView(frame: window.bounds)
   overView?.backgroundColor = UIColor.red.withAlphaComponent(0.4)

   let windowCount = UIApplication.shared.windows.count
   UIApplication.shared.windows[windowCount-1].addSubview(overView!)
}

func removeOverView() { // CALL THIS WHEN RESPONSE RECEIVED

    overView?.removeFromSuperview()
}

Output Way 2:

enter image description here

Way 1:

Use UTextView Delegate,

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    if isSendBtnClicked == true {

        return false
    }


    return true
}



@IBAction func sendButtonClicked(_ sender: UIButton) {

    // Disable textview and send button while message is being sent
    self.isSendBtnClicked = true
    sendButton.isEnabled = false

    fetchSendMessage( ) { (result, error) in
        if error != nil {
            ShowDialog.showDialog(title: nil, message: (error?.localizedDescription)!, viewController: self)
        } else {
            if (result?.success)! {
                self.arry = (result?.data)!

                self.fetchMessages(page: 1, completed: {
                    self.insertNewMessage(sentMessage)
                })

                // Clear the message & Enable textview and send button
                self.isSendBtnClicked = false
                self.messageTextView.text = "Type Message"
                self.messageTextView.textColor = UIColor.greyColour
                self.sendButton.isEnabled = true
                self.messageTextView.endEditing(true)
            } else {
                ShowDialog.showDialog(title: "Message not sent", message: (result?.errors![0].message)!, viewController: self)

                // Retain typed message
                // Enable textview and send button
                self.isSendBtnClicked = false
                self.sendButton.isEnabled = true
            }
        }
    }
}

Once user click, send button, Keyboard will not hide and user can type but it will not enter in that textview untill response receive from fetchSendMessage()

0
votes

You can override a method in UITextViewDelegate

func textViewShouldEndEditing(UITextView) -> Bool

Have this method return false and the UITextView shouldn't resign first responder, ie close the keyboard.