web-dev-qa-db-fra.com

Comment ignorer le clavier lorsque vous touchez n'importe où en dehors de UITextField (dans Swift)?

Je travaille sur un projet qui a un UIViewController, sur le contrôleur de vue il y a un UIScrollView et un UITextField sur le scrollview . Comme ceci:   J'essaie de fermer le clavier et de le masquer après avoir tapé du texte dans le champ de texte et tapé n'importe où en dehors du champ de texte . J'ai essayé le code suivant:

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

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

Cela fonctionne pour moi lorsque je tape en dehors de la vue de défilement, mais lorsque je tape sur la vue de défilement, rien ne se passe et le clavier ne se cache pas.

Est-il possible de fermer le clavier lorsque vous appuyez sur n'importe où en dehors du champ de texte? Merci

53
White Hat

Édité pour Swift 4

Edit: Ajouté @objc. Bien que ce ne soit pas la meilleure option en termes de performances, une instance de celle-ci ne devrait pas causer trop de problèmes tant qu'il n'y aura pas de meilleure solution.

Modifié pour corriger le besoin d'interagir avec des éléments derrière GestureRecognizer.

Edit: Merci @Rao pour le signaler. Ajout du tap.cancelsTouchesInView = false.

Cela devrait vous aider à avoir plusieurs UITextView ou UITextField

Créez une extension du contrôleur de vue. Cela a fonctionné beaucoup plus facilement pour moi et avec moins de tracas que d'essayer d'utiliser .resignFirstResponder()

extension UIViewController
{
    func hideKeyboard()
    {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(
            target: self,
            action: #selector(UIViewController.dismissKeyboard))

        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

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

Appelez self.hideKeyboard() dans le viewDidLoad

98
Matthew Bradshaw

Essayez ceci, il est testé et fonctionne:

Pour Swift 3.0/4.0

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

Pour les vieux swift  

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
    self.view.endEditing(true)
}
55
iAnurag

Dans ce cas, UITapGesture fait partie des choix possibles. J'ai essayé de créer un exemple de code au cas où. Comme ça,

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var scrollView: UIScrollView!

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

        let tapGesture = UITapGestureRecognizer(target: self, action: "tap:")
        view.addGestureRecognizer(tapGesture)
    }

    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
}
13
pixyzehn

Swift 3

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
13
Giang

Solution de travail pour Swift 3 fonctionnant avec ScrollView

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // The next line is the crucial part
        // The action is where Swift 3 varies from previous versions
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tap(gesture:)))
        self.view.addGestureRecognizer(tapGesture)
    }

    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
}

Une autre question qui parle de ce problème que j’ai référé et utilisé. La réponse acceptée ne fonctionne plus dans Swift 3. La réponse actuellement sélectionnée doit être la réponse ci-dessous.

11
Devbot10

Détails

xCode 8.2.1, Swift 3

Tâche

Définissez UITapGestureRecognizer pour une vue de UIViewController qui fermera le clavier et transformera cette fonctionnalité en propriété Bool de UIView.

Implémentation complexe mais utilisation en une ligne

classe TapGestureRecognizer

import UIKit

class TapGestureRecognizer: UITapGestureRecognizer {

    let identifier: String

    private override init(target: Any?, action: Selector?) {
        self.identifier = ""
        super.init(target: target, action: action)
    }

    init(target: Any?, action: Selector?, identifier: String) {
        self.identifier = identifier
        super.init(target: target, action: action)
    }

    static func == (left: TapGestureRecognizer, right: TapGestureRecognizer) -> Bool {
        return left.identifier == right.identifier
    }
}

extension UIView

import UIKit

extension UIView {

    private var disableKeybordWhenTappedGestureRecognizerIdentifier:String {
        return "disableKeybordWhenTapped"
    }

    private var disableKeybordWhenTappedGestureRecognizer: TapGestureRecognizer? {

        let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: disableKeybordWhenTappedGestureRecognizerIdentifier)

        if let gestureRecognizers = self.gestureRecognizers {
            for gestureRecognizer in gestureRecognizers {
                if let tapGestureRecognizer = gestureRecognizer as? TapGestureRecognizer, tapGestureRecognizer == hideKeyboardGesture, tapGestureRecognizer == hideKeyboardGesture {
                    return tapGestureRecognizer
                }
            }
        }
        return nil
    }

    @objc private func hideKeyboard() {
        endEditing(true)
    }

    var disableKeybordWhenTapped: Bool {

        set {
            let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: disableKeybordWhenTappedGestureRecognizerIdentifier)

            if let disableKeybordWhenTappedGestureRecognizer = self.disableKeybordWhenTappedGestureRecognizer {
                removeGestureRecognizer(disableKeybordWhenTappedGestureRecognizer)
                if gestureRecognizers?.count == 0 {
                    gestureRecognizers = nil
                }
            }

            if newValue {
                addGestureRecognizer(hideKeyboardGesture)
            }
        }

        get {
            return disableKeybordWhenTappedGestureRecognizer == nil ? false : true
        }
    }
}

Usage

view.disableKeybordWhenTapped = true

Échantillon complet

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 30))
        textField.borderStyle = .roundedRect
        textField.placeholder = "Enter text"
        view.addSubview(textField)

        view.disableKeybordWhenTapped = true
    }
}
5
Vasily Bodnarchuk

Regarde ça.

override func viewDidLoad() {
    var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
    self.view.userInteractionEnabled = true
    self.view.addGestureRecognizer(tapGesture)
}

Ensuite, votre gestionnaire de tap est.

  func handleTap(sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}
5
handiansom

Pour Swift 3

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

Cela fonctionne lorsque vous touchez hors de la zone de saisie pour un nombre quelconque d'éléments de saisie.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
2
Venkat Ram

Chaque touche différente de champ de texte quitte le clavier ou utilise resignfirstresponder

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch *touch = [touches anyObject];
 if(![touch.view isMemberOfClass:[UITextField class]]) {
     [touch.view endEditing:YES];
 }
}
1
Miguel Monteiro

J'ai eu le même problème et je l'ai finalement résolu!

Définir un TapGestureRecognizer dans votre Storyboard, puis une prise dans votre ViewController

@IBOutlet var tapGesture: UITapGestureRecognizer!

Puis définissez une action IBAction dans votre ViewController

@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
 self.view.endEditing(true)
} 

ajoute ces lignes à votre méthode viewDidLoad

override func viewDidLoad()
{
    super.viewDidLoad()
    self.view.addGestureRecognizer(tapGesture)
}

et ça devrait marcher

J'espère que ça va aider!

1
Lynkz7
func findAndResignFirstResponder(_ stView: UIView) -> Bool {

    if stView.isFirstResponder {
        stView.resignFirstResponder()
        return true
    }
    for subView: UIView in stView.subviews {
        if findAndResignFirstResponder(subView) {
            return true
        }
    }
    return false
}
1
Subhajit

Allez dans Type de clavier et sélectionnez Par défaut ou tout ce dont vous avez besoin pour TextField. Puis redéfinissez une méthode, appelez-la comme vous voulez, j'appelle généralement touchingBegins. Ci-dessous ce que vous avez oublié d'ajouter

super.touchingBegins(touches, withEvent: event)
 }
0
Katz

J'ai créé cette méthode dans Obj-C qui cache un clavier, peu importe où l'utilisateur tape actuellement:

//call this method
+ (void)hideKeyboard {
    //grab the main window of the application
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    //call our recursive method below
    [self resignResponderForView:window];
}

//our recursive method
+ (void)resignResponderForView:(UIView *)view {
    //resign responder from this view
    //If it has the keyboard, then it will hide the keyboard
    [view resignFirstResponder];
    //if it has no subviews, then return back up the stack
    if (view.subviews.count == 0)
        return;
    //go through all of its subviews
    for (UIView *subview in view.subviews) {
        //recursively call the method on those subviews
        [self resignResponderForView:subview];
    }
}

J'espère que cela peut être traduit en Swift et qu'il a du sens. Il peut être appelé n'importe où dans l'application et cachera le clavier, peu importe le type de lecteur VC ou autre.

0
AlexKoren

Présentez un outil de reconnaissance des gestes du toucher, définissez-le et actionnez-le 

Utilisez le code:

nom de votre champ de texte . resignfirstresponder ()

0
kuni

Dans Swift4

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

// Dans Swift 4..Il a fonctionné pour moi.

func setupKeyboardDismissRecognizer(){
    let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(searchingActivity.dismissKeyboard))

    self.view.addGestureRecognizer(tapRecognizer)
}

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

// Appelez cette fonction setupKeyboardDismissRecognizer () dans viewDidLoad

0
Raghib Arshi