web-dev-qa-db-fra.com

Fermez le clavier iOS en touchant n’importe où en utilisant Swift

J'ai cherché cela partout mais je n'arrive pas à le trouver. Je sais comment écarter le clavier en utilisant Objective-C mais je ne sais pas comment faire cela en utilisant Swift? Est-ce que quelqu'un sait?

363
lagoon
override func viewDidLoad() {
    super.viewDidLoad()

    //Looks for single or multiple taps. 
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")

    //Uncomment the line below if you want the tap not not interfere and cancel other interactions.
    //tap.cancelsTouchesInView = false 

    view.addGestureRecognizer(tap)
}

//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {
    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)
}

Voici une autre façon de faire cette tâche si vous allez utiliser cette fonctionnalité dans plusieurs UIViewControllers:

// Put this piece of code anywhere you like
extension UIViewController {
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false            
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
        view.endEditing(true)
    }
}

Maintenant dans chaque UIViewController, tout ce que vous avez à faire est d'appeler cette fonction:

override func viewDidLoad() {
    super.viewDidLoad()
    self.hideKeyboardWhenTappedAround() 
}

Cette fonction est incluse en tant que fonction standard dans mon référentiel, qui contient de nombreuses extensions Swift telles que celle-ci, consultez-la: https://github.com/goktugyil/EZSwiftExtensions =

1178
Esqarrouth

Une réponse à votre question sur la suppression du clavier dans Xcode 6.1 à l'aide de Swift ci-dessous:

import UIKit

class ItemViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var textFieldItemName: UITextField!

    @IBOutlet var textFieldQt: UITextField!

    @IBOutlet var textFieldMoreInfo: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

        textFieldItemName.delegate = self
        textFieldQt.delegate = self
        textFieldMoreInfo.delegate = self
    }

                       ...

    /**
     * Called when 'return' key pressed. return NO to ignore.
     */
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }


   /**
    * Called when the user click on the view (outside the UITextField).
    */
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }

}

( Source de cette information ).

111
King-Wizard

Tu peux appeler

resignFirstResponder()

sur n'importe quelle instance d'un UIResponder, telle qu'un UITextField. Si vous l'appelez dans la vue qui provoque l'affichage du clavier, celui-ci est désactivé.

35
Dash

Swift 4 de travail

Créez une extension comme ci-dessous et appelez hideKeyboardWhenTappedAround() dans votre contrôleur de vue de base.

//
//  UIViewController+Extension.Swift
//  Project Name
//
//  Created by ABC on 2/3/18.
//  Copyright © 2018 ABC. All rights reserved.
//

import UIKit

extension UIViewController {
    func hideKeyboardWhenTappedAround() {
        let tapGesture = UITapGestureRecognizer(target: self, 
                         action: #selector(hideKeyboard))
        view.addGestureRecognizer(tapGesture)
    }

    @objc func hideKeyboard() {
        view.endEditing(true)
    }
}
28
Fahim Parkar
//Simple exercise to demonstrate, assuming the view controller has a //Textfield, Button and a Label. And that the label should display the //userinputs when button clicked. And if you want the keyboard to disappear //when clicken anywhere on the screen + upon clicking Return key in the //keyboard. Dont forget to add "UITextFieldDelegate" and 
//"self.userInput.delegate = self" as below

import UIKit

class ViewController: UIViewController,UITextFieldDelegate {

    @IBOutlet weak var userInput: UITextField!
    @IBAction func transferBtn(sender: AnyObject) {
                display.text = userInput.text

    }
    @IBOutlet weak var display: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

//This is important for the textFieldShouldReturn function, conforming to textfieldDelegate and setting it to self
        self.userInput.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

//This is for the keyboard to GO AWAYY !! when user clicks anywhere on the view
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }


//This is for the keyboard to GO AWAYY !! when user clicks "Return" key  on the keyboard

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

}
19
Naishta

pour Swift 3 c'est très simple

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

si vous voulez masquer le clavier en appuyant sur la touche Retour

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

mais dans le second cas, vous devrez également transmettre le délégué de tous les textField au ViewController du Main.Storyboard.

17
Yerbol

Swift 3: le moyen le plus simple de supprimer un clavier:

  //Dismiss keyboard method
    func keyboardDismiss() {
        textField.resignFirstResponder()
    }

    //ADD Gesture Recignizer to Dismiss keyboard then view tapped
    @IBAction func viewTapped(_ sender: AnyObject) {
        keyboardDismiss()
    }

    //Dismiss keyboard using Return Key (Done) Button
    //Do not forgot to add protocol UITextFieldDelegate 
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        keyboardDismiss()

        return true
    }
10
NikaE

La réponse de Dash est correcte et préférée. Une approche plus "terre brûlée" consiste à appeler view.endEditing(true). Cela provoque view et toutes ses sous-vues à resignFirstResponder. Si vous ne faites pas référence à la vue que vous souhaitez rejeter, il s'agit d'une solution simpliste mais efficace.

Notez que personnellement, je pense que vous devriez avoir une référence à la vue que vous souhaitez voir démissionner du premier répondant. .endEditing(force: Bool) est une approche barbare; s'il vous plaît ne l'utilisez pas.

10
modocache

Dans le storyboard:

  1. sélectionnez la TableView
  2. à droite, sélectionnez l'inspecteur d'attributs
  3. dans la section clavier - sélectionnez le mode de licenciement souhaité
9
goggelj

Swift 3:

Extension avec Selector en tant que paramètre pour pouvoir ajouter des éléments supplémentaires dans la fonction de suppression et cancelsTouchesInView pour éviter toute distorsion lors du contact avec d'autres éléments de la vue.

extension UIViewController {
    func hideKeyboardOnTap(_ selector: Selector) {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: selector)
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }
}

Usage:

override func viewDidLoad() {
    super.viewDidLoad()
    self.hideKeyboardOnTap(#selector(self.dismissKeyboard))
}

func dismissKeyboard() {
    view.endEditing(true)
    // do aditional stuff
}
9
David Seek

! [comment désactiver le clavier ..] [1]

import UIKit

class ViewController: UIViewController,UITextFieldDelegate {

   @IBOutlet weak var username: UITextField!
   @IBOutlet weak var password: UITextField!

   override func viewDidLoad() {
      super.viewDidLoad() 
      username.delegate = self
      password.delegate = self
      // Do any additional setup after loading the view, typically from a nib.
   }

   override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
   }

   func textFieldShouldReturn(textField: UITextField!) -> Bool // called when   'return' key pressed. return NO to ignore.
   {
      textField.resignFirstResponder()
      return true;
   }

   override func touchesBegan(_: Set<UITouch>, with: UIEvent?) {
     username.resignFirstResponder()
     password.resignFirstResponder()
     self.view.endEditing(true)
  }
}
8
hardik bar

Si vous utilisez une vue de défilement, cela pourrait être beaucoup plus simple.

Il suffit de sélectionner Dismiss interactively dans le storyboard.

7
JIE WANG

Dans Swift 4, ajoutez @objc:

Dans le viewDidLoad:

let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard))
view.addGestureRecognizer(tap)

Une fonction:

@objc func dismissKeyboard() {
  view.endEditing(true)
}
6
user3856297

J'ai trouvé que la meilleure solution incluait la réponse acceptée de @Esqarrouth, avec quelques ajustements:

extension UIViewController {
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboardView")
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    func dismissKeyboardView() {
        view.endEditing(true)
    }
}

La ligne tap.cancelsTouchesInView = false était critique: elle garantit que la UITapGestureRecognizer n'empêche pas les autres éléments de la vue de recevoir une interaction de l'utilisateur.

La méthode dismissKeyboard() a été remplacée par la dismissKeyboardView() un peu moins élégante. Ceci est dû au fait que, dans la base de code relativement ancienne de mon projet, il y avait eu de nombreuses fois où dismissKeyboard() était déjà utilisé (j'imagine que cela n'est pas inhabituel), ce qui posait des problèmes pour le compilateur.

Ensuite, comme ci-dessus, ce comportement peut être activé dans des contrôleurs de vue individuels:

override func viewDidLoad() {
    super.viewDidLoad()
    self.hideKeyboardWhenTappedAround() 
}
6
Luke Harries
  import UIKit

  class ItemViewController: UIViewController, UITextFieldDelegate {

  @IBOutlet weak var nameTextField: UITextField!

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

    // Called when 'return' key pressed. return NO to ignore.

    func textFieldShouldReturn(textField: UITextField) -> Bool {

            textField.resignFirstResponder()
             return true
     }

 // Called when the user click on the view (outside the UITextField).

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)    {
      self.view.endEditing(true)
  }
}
5
Prashant chaudhary

En tant que programmeur débutant, il peut être déroutant que les gens produisent des réponses plus habiles et inutiles ... Vous n'avez rien à faire des choses compliquées montrées ci-dessus! ...

Voici l'option la plus simple ... Dans le cas où votre clavier apparaît en réponse au champ de texte - Dans votre fonction d'écran tactile, ajoutez simplement la fonction resignFirstResponder. Comme indiqué ci-dessous - le clavier se ferme car le premier répondeur est libéré (sortie de la chaîne de répondeur) ...

override func touchesBegan(_: Set<UITouch>, with: UIEvent?){
    MyTextField.resignFirstResponder()
}
5
RedSky

Ajoutez cette extension à votre ViewController:

  extension UIViewController {
// Ends editing view when touches to view 
  open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event)
    self.view.endEditing(true)
  }
}
4
Jarvis The Avenger

Ce doublon démissionne du clavier de tout (tout) UITextField dans un UIView

self.view.endEditing(true)
4
Satnam Sync

Dans Swift, vous pouvez utiliser

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

}
4
bernard rayoso

J'ai utiliser IQKeyBoardManagerSwift pour le clavier. C'est facile a utiliser. il suffit d'ajouter le module 'IQKeyboardManagerSwift'

Importez IQKeyboardManagerSwift et écrivez le code sur didFinishLaunchingWithOptions dans AppDelegate.

///add this line 
IQKeyboardManager.shared.shouldResignOnTouchOutside = true
IQKeyboardManager.shared.enable = true
4
Sukhwinder Singh

J'utilise toujours ce qui suit:

UIApplication.shared.keyWindow?.endEditing(true)

Ou même comme une extension:

extension UIApplication {

    /// Dismiss keyboard from key window.
    /// Example Usage: `UIApplication.endEditing(true)`.
    ///
    /// - Parameters:
    ///     - force: specify `true` to force first responder to resign.
    open class func endEditing(_ force: Bool = false) {
        shared.keyWindow?.endEditing(force)
    }
}

De cette façon, si la classe dans laquelle j'essaie d'annuler l'édition n'a pas de propriété view ou n'est pas une sous-classe de UIView, je peux simplement appeler UIApplication.endEditing(true).

4
NoodleOfDeath

Swift 5 deux lignes suffisent. Ajouter dans votre viewDidLoad devrait fonctionner.

 let tapGesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing))
 view.addGestureRecognizer(tapGesture)

Si votre tape a bloqué d'autres touches, ajoutez cette ligne:

tapGesture.cancelsTouchesInView = false
3
William Hu

pour Swift

Enregistrer un identificateur d'événement dans viewDidLoad

let tap = UITapGestureRecognizer(target: self, action: #selector(hideKeyBoard))

ensuite, nous devons ajouter le geste dans la vue dans le même viewDidLoad.

self.view.addGestureRecognizer(tap)

Ensuite, nous devons initialiser la méthode enregistrée

func hideKeyBoard(sender: UITapGestureRecognizer? = nil){
    view.endEditing(true)
}
3
Sandu

Si vous avez d'autres vues qui devraient recevoir le toucher, vous devez définir cancelsTouchesInView = false

Comme ça:

let elsewhereTap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    elsewhereTap.cancelsTouchesInView = false
    self.view.addGestureRecognizer(elsewhereTap)
2
ph1lb4

Une autre possibilité consiste simplement à ajouter un gros bouton sans contenu situé sous toutes les vues que vous pourriez avoir besoin de toucher. Donnez-lui une action nommée:

@IBAction func dismissKeyboardButton(sender: AnyObject) {
    view.endEditing(true)
}

Le problème avec une reconnaissance de geste était pour moi, car il capturait également toutes les retouches que je voulais recevoir par la tableViewCells.

2
Timm Kent
override func viewDidLoad() {
        super.viewDidLoad()

self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap)))

}

func tap(sender: UITapGestureRecognizer){
        print("tapped")
        view.endEditing(true)
}

Essayez ceci, ça marche

2
Ramprasath Selvam

Je t'ai eu la fam

override func viewDidLoad() {
    super.viewDidLoad() /*This ensures that our view loaded*/
    self.textField.delegate = self /*we select our text field that we want*/   
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: Selector("dismissKeyboard")))
}

func dismissKeyboard(){ /*this is a void function*/
    textField.resignFirstResponder() /*This will dismiss our keyboard on tap*/
}
1
ChannelJuanNews

J'ai travaillé sur uisearchbar. Voir le mien.

import UIKit

class BidderPage: UIViewController,UISearchBarDelegate,UITableViewDataSource {

     let recognizer = UITapGestureRecognizer()

// Set recogniser as public in case of tableview and didselectindexpath.


    func searchBarTextDidBeginEditing(searchBar: UISearchBar)

    {

        recognizer.addTarget(self, action: "handleTap:")
        view.addGestureRecognizer(recognizer)

    }

    func handleTap(recognizer: UITapGestureRecognizer) {
        biddersearchbar .resignFirstResponder()
    }
    func searchBarTextDidEndEditing(searchBar: UISearchBar)
    {
        view .removeGestureRecognizer(recognizer)

    }
1
A.G

Une seule ligne de code dans la méthode viewDidLoad():

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
1
Artem

Swift 3

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

Quand il y a plus d'un champ de texte dans la vue

Pour suivre recommandation de @ modocache afin d'éviter d'appeler view.endEditing(), vous pouvez garder une trace du champ de texte devenu premier répondant, mais c'est compliqué et source d'erreurs.

Une alternative consiste à appeler resignFirstResponder() sur tous les champs de texte du contrôleur de vue . Voici un exemple de création d'une collection de tous les champs de texte (ce qui dans mon cas était nécessaire pour le code de validation de toute façon):

@IBOutlet weak var firstName: UITextField!
@IBOutlet weak var lastName: UITextField!
@IBOutlet weak var email: UITextField!

var allTextFields: Array<UITextField>!  // Forced unwrapping so it must be initialized in viewDidLoad
override func viewDidLoad()
{
    super.viewDidLoad()
    self.allTextFields = [self.firstName, self.lastName, self.email]
}

Avec la collection disponible, il est simple de les parcourir toutes:

private func dismissKeyboard()
{
    for textField in allTextFields
    {
        textField.resignFirstResponder()
    }
}

Alors maintenant, vous pouvez appeler dismissKeyboard() dans votre identificateur de geste (ou à tout autre endroit qui vous convient). L'inconvénient est que vous devez conserver la liste de UITextFields lorsque vous ajoutez ou supprimez des champs.

Commentaires bienvenus. S'il y a un problème avec l'appel de resignFirstResponder() sur des commandes qui ne sont pas des premiers répondants, ou s'il existe un moyen simple et garanti de suivre le premier répondant actuel, j'aimerais beaucoup en entendre parler!

1
stone

Voici une façon succincte de le faire:

let endEditingTapGesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:)))
endEditingTapGesture.cancelsTouchesInView = false
view.addGestureRecognizer(endEditingTapGesture)
1
Sam

Je préfère ceci one-liner:

view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "dismissKeyboardFromView:"))

Il suffit de mettre cela dans la fonction viewDidLoad de substitution dans le sous-groupe UIViewController de votre choix, puis de placer le code suivant dans un nouveau fichier vide de votre projet appelé "UIViewController + renvoiKeyboard.Swift":

import UIKit

extension UIViewController {
    // This function is called when the tap is recognized
    func dismissKeyboardFromView(sender: UITapGestureRecognizer?) {
        let view = sender?.view
        view?.endEditing(true)
    }
}
1
gammachill

Vous pouvez également ajouter un outil de reconnaissance des gestes tactiles pour renoncer au clavier. :RÉ

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let recognizer = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
    backgroundView.addGestureRecognizer(recognizer)
}
    func handleTap(recognizer: UITapGestureRecognizer) {
    textField.resignFirstResponder()
    textFieldtwo.resignFirstResponder()
    textFieldthree.resignFirstResponder()

    println("tappped")
}
1
Satnam Sync

J'ai trouvé cette solution simple: 1. Ajoutez UITapGestureRecognizer à votre vue Controller. 2. Ajoutez IBAction à votre UITapGestureRecognizer 3. Enfin, vous pouvez démissionner du premier répondant.

class ViewController: UIViewController
{

@IBOutlet var tap: UITapGestureRecognizer!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad()
{
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}


@IBAction func dismissUsingGesture(_ sender: UITapGestureRecognizer)
{
   self.textField.resignFirstResponder()
    label.text = textField.text!
}
}
1
Atka

Publication en tant que nouvelle réponse depuis que ma modification de la réponse de @ King-Wizard a été rejetée.

Faites de votre classe un délégué de UITextField et remplacez touchesBegan.

Swift 4

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var textField: UITextField!

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

    //Called when 'return' key is pressed. Return false to keep the keyboard visible.
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        return true
    }

    // Called when the user clicks on the view (outside of UITextField).
    override func touchesBegan(touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

}
1
Viktor Seč

Un exemple de Swift4 + RxSwift (importez également RxGesture)

view.rx.tapGesture()
        .when(GestureRecognizerState.recognized)
        .subscribe({ _ in
            self.view.endEditing(true)
        })
        .disposed(by: disposeBag)
0
norbDEV