71

I am sure this is not that difficult, but I am having trouble finding info on how to dismiss a keyboard with the return/done key using a textview, not a textfield. here is what I have tried so far(which works with a textfield.)

Thanks very much in advance for any help!

// PostTravelQuestion.swift class PostTravelQuestion: UIViewController, UITextViewDelegate { @IBAction func closepostpage(sender: AnyObject) { dismissViewControllerAnimated(true, completion: nil) } @IBOutlet var postquestion: UITextView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. postquestion.delegate = self } self addDoneToolBarToKeyboard:self.textView /*func textViewShouldEndEditing(textView: UITextView) -> Bool { textView.resignFirstResponder() return true }*/ /*override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { postquestion.resignFirstResponder() self.view.endEditing(true) }*/ override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func textViewShouldReturn(textView: UITextView!) -> Bool { self.view.endEditing(true); return true; } } 

6 Answers 6

201

This works for me:

import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self } /* Updated for Swift 4 */ func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if(text == "\n") { textView.resignFirstResponder() return false } return true } /* Older versions of Swift */ func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { if(text == "\n") { textView.resignFirstResponder() return false } return true } } 
Sign up to request clarification or add additional context in comments.

4 Comments

ok, thanks a bunch. Just as an additional side question, Is there any real difference/best practices between uiTextFields and uiTExtViews...(Besides the dimensions)?
To be honest, I just look up how the class or protocol is implemented behind the scenes and all the available functions, properties, etc. Then I read all the Apple text comments and think about the intent of each class/protocol and why the different features are available.
In Swift 1.2 it should be func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool
var isNewline: Bool { get } iOS 8+
55

Add UITextViewDelegate to your class and then set your delegate for your textView or your textField in viewDidLoad. Should look something like this:

// in viewDidLoad textField.delegate = self textView.delegate = self 

Swift 3

// hides text views func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if (text == "\n") { textView.resignFirstResponder() return false } return true } // hides text fields func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if (string == "\n") { textField.resignFirstResponder() return false } return true } 

Swift 2.0

The below syntax has been tested for Swift 1.2 & Swift 2.0

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { if(text == "\n") { textView.resignFirstResponder() return false } return true } 

1 Comment

I was working with a UITextView, so I did the //hide text views code and it worked after loads of StackOverflow searching!
19

Below code will dismissing the keyboard when click return/done key on UITextView.

In Swift 3.0

import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if(text == "\n") { view.endEditing(true) return false } else { return true } } 

In Swift 2.2

func textView(textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if text == "\n" { view.endEditing(true) return false } else { return true } } 

Comments

5

Easiest and best way to do this using UITextView Extension.
Credit: http://www.swiftdevcenter.com/uitextview-dismiss-keyboard-swift/
Your ViewController Class

class ViewController: UIViewController { @IBOutlet weak var myTextView: UITextView! override func viewDidLoad() { super.viewDidLoad() // 1 self.myTextView.addDoneButton(title: "Done", target: self, selector: #selector(tapDone(sender:))) } // 2 @objc func tapDone(sender: Any) { self.view.endEditing(true) } } 

Add UITextView Extension

extension UITextView { func addDoneButton(title: String, target: Any, selector: Selector) { let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 44.0))//1 let flexible = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)//2 let barButton = UIBarButtonItem(title: title, style: .plain, target: target, action: selector)//3 toolBar.setItems([flexible, barButton], animated: false)//4 self.inputAccessoryView = toolBar//5 } } 

For more detail: visit full documentation

Comments

4

to hide the keyboard touch on any part outside the textbox or textviews in swift 4 use this peace of code in the ViewController class:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { view.endEditing(true) super.touchesBegan(touches, with: event) } 

Regards

1 Comment

I believe calling super in this instance should be: super.touchesBegan(touches, with: event)
0

Building on the answers of others (kudos!), here is my minimalistic take on it:

import UIKit extension UITextView { func withDoneButton(toolBarHeight: CGFloat = 44) { guard UIDevice.current.userInterfaceIdiom == .phone else { print("Adding Done button to the keyboard makes sense only on iPhones") return } let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: toolBarHeight)) let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(endEditing)) toolBar.setItems([flexibleSpace, doneButton], animated: false) inputAccessoryView = toolBar } } 

Usage:

override func viewDidLoad() { super.viewDidLoad() textView.withDoneButton() } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.