Onichan
Onichan

Reputation: 4516

inputAccessoryView Dismiss Keyboard

I have a textView docked to the bottom of the view. However, the keyboard wont dismiss when the user taps outside the commentTextView.

Current Attempt:

import UIKit
class CommentsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet var commentBar: UIView!

    @IBOutlet var commentTextField: UITextField!

    override var inputAccessoryView: UIView {
        return commentBar
    }

    override func canBecomeFirstResponder() -> Bool {
        commentBar.removeFromSuperview()
        return true
    }

    func textFieldShouldReturn(textField: UITextField!) -> Bool {
        self.view.endEditing(true);
        return false;
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.view.endEditing(true);
        commentTextField.resignFirstResponder()
    }

Upvotes: 9

Views: 4636

Answers (7)

Istvan
Istvan

Reputation: 1249

Modify

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.view.endEditing(true);
        commentTextField.resignFirstResponder()
    }

To

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        self.view.endEditing(true)
    }

It should do the job.

Upvotes: 1

Will M.
Will M.

Reputation: 1854

First, your view controller needs to implement UITextFieldDelegate, so add that. Then, set your view controller as the delegate for the textfield

enter image description here

then add these methods. The first one will resignFirstResponder when your text field ends editing. The second resigns when you hit return. The last forces your textfield to end editing when you tap the background.

func textFieldDidEndEditing(textField: UITextField) {
    textField.resignFirstResponder()
} 

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    self.commentTextField.endEditing(true)
}

Upvotes: 1

Britto Thomas
Britto Thomas

Reputation: 2120

Try to set keyboard resign on your tableview as shown in figure.

check any -dismiss on drag -dismiss interactively

Set keyboard release on tableview interations

Upvotes: 4

Yuchen
Yuchen

Reputation: 33036

According to Apple's documentation, the keyboard won't dismiss by default when the user taps outside of the UITextView. You do need to handle this programmatically when you want to dismiss the keyboard by calling commentTextField.resignFirstResponder().

UITextFiled Reference about Managing the Keyboard

It is your application’s responsibility to dismiss the keyboard at the time of your choosing. You might dismiss the keyboard in response to a specific user action, such as the user tapping a particular button in your user interface. To dismiss the keyboard, send the resignFirstResponder message to the text view that is currently the first responder.

There are many ways for a user may hide the keyboard.

Situation 1: one is when the user tap on the Return button on the keyboard. This is exactly what your following function is for:

func textFieldShouldReturn(textField: UITextField!) -> Bool {
    commentTextField.resignFirstResponder();
    return true;
}

But the major problem is that the above function won't get called because you forget to set the UITextFieldDelegate. In short, you need to change the class definition to the following:

class CommentsViewController: UIViewController, UITextFieldDelegate /*Add This*/, UITableViewDelegate, UITableViewDataSource {
    // ....
}

You will also have to set the delete either in the storyboard or by code. It is the same as setting the UITableViewDelegate and UITableViewDataSource. By the following is an example of setting it in code:

override func viewDidLoad() {
    super.viewDidLoad()
    commentTextField.delegate = self;
}

Situation 2: when user tap on the table view. You can simply implement the following UITableViewDelegate and it should work.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    commentTextField.resignFirstResponder();
}

Situation 3: when the user tap on a background view. This is what the following code is for. However, this function will not get called when user is tap on the table view. If you want to know why, please refer to the responder chain for more details.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    // self.view.endEditing(true); // This line is redundant. 
    commentTextField.resignFirstResponder()
}

To sum up, there is no quick and easy way to dismiss the keyboard say "when the user taps outside the textView". You do need to handle all different situations according to your need.

enter image description here

Upvotes: 7

vrwim
vrwim

Reputation: 14260

When you say "outside of my UITextField", I'm guessing you mean "on another element in my view". I can see that you have a UITableViewDelegate and UITableViewDataSource, which tells me you have a tableView inside CommentsViewController.

You can implement the function func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) and there you can resign the keyboard by calling commentTextField.resignFirstResponder()

Upvotes: 1

nathanwhy
nathanwhy

Reputation: 6134

did you add Table View?

if yes, tableViewCell will receive the touch event instead of controller.view.

you could override the method in custom tableView cell:

override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        if (xxTextField.isFirstResponder){
            return viewController.view
        }
   return self 
}

Another way you can try,maybe it work:

add UITapGestureRecognizer to controller.view.

Upvotes: 1

u54r
u54r

Reputation: 1805

Try this

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    self.view.endEditing(true);
    commentTextField.resignFirstResponder()
}

Upvotes: -1

Related Questions