Comment désactiver le clavier lorsque vous touchez n'importe où en dehors D'UITextField (dans swift)?

je travaille sur un projet qui a un Controller UIViewController, sur le Controller view Il y a un UIScrollView et un UITextField sur le scrollview. pareil: J'essaie de rejeter le clavier et de le cacher après avoir tapé du texte dans la zone de texte et avoir tapé n'importe où en dehors de la zone 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)
}

ça marche pour moi quand je tape à l'extérieur du scrollview, mais quand je tape sur le scrollview rien ne se passe et le clavier ne se cache pas.

y a-t-il un moyen de rejeter le clavier en tapant n'importe où à l'extérieur du champ de texte? merci

50
demandé sur White Hat 2015-08-29 03:55:31

15 réponses

édité pour Swift 4

Edit: Ajout De @objc . Bien que ce ne soit pas la meilleure option pour la performance, un exemple de cela ici ne devrait pas causer trop de problèmes jusqu'à ce qu'il y ait une meilleure solution.

modifié pour corriger lors de la nécessité d'interagir avec des éléments derrière GestureRecognizer.

Edit: Merci @Rao pour le rappeler. Ajouté tap.cancelsTouchesInView = false .

cela devrait vous aider à avoir multiple UITextView ou UITextField

crée une extension du contrôleur de vue. Cela a beaucoup plus lisse 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)
    }
}

Appel self.hideKeyboard() dans le viewDidLoad

86
répondu Matthew Bradshaw 2018-09-04 17:24:35

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)
}

"151950920 De L'Ancienne Swift

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
    self.view.endEditing(true)
}
51
répondu iAnurag 2017-07-21 10:53:07

dans ce cas, il y a UITapGesture comme l'un des choix. J'ai essayé de créer un code au cas où. Comme ceci,

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
répondu pixyzehn 2015-08-29 01:34:06

solution de travail pour Swift 3 qui fonctionne 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 cette question que j'ai mentionnée et utilisée. La réponse acceptée ne fonctionne plus dans Swift 3. La réponse actuellement choisie devrait être la réponse ci-dessous.

11
répondu Devbot10 2017-05-23 12:34:45

swift 3

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
11
répondu Giang 2017-05-13 04:53:52

détails

xCode 8.2.1, Swift 3

tâche

définit UITapGestureRecognizer pour la vue de UIViewController qui fermera le clavier et fera de cette fonctionnalité la propriété de Bool D'UIView.

implémentation complexe mais l'usage est en une ligne

class 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
    }
}

l'extension de 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
        }
    }
}

Utilisation

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
répondu Vasily Bodnarchuk 2017-02-12 11:58:57

regardez ça.

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

alors votre gestionnaire de claquettes l'est.

  func handleTap(sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}
4
répondu handiansom 2017-04-27 02:41:51

cela fonctionne lorsqu'on touche une zone d'entrée extérieure pour n'importe quel nombre d'éléments d'entrée.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
2
répondu Venkat Ram 2016-08-19 10:47:27

Pour Swift 3

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
}
2
répondu Davina Arnold 2018-08-07 03:45:09

j'ai eu le même problème et je l'ai enfin trouvé !

mettez un TapGestureRecognizer dans votre Storyboard et ensuite une sortie dans votre ViewController

@IBOutlet var tapGesture: UITapGestureRecognizer!

puis définissez une IBAction dans votre ViewController

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

ajoutez ces lignes à votre méthode viewDidLoad

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

et son devrait fonctionner

Espère que cela va vous aider !

1
répondu Lynkz7 2015-10-27 16:10:54

chaque touche différente de zone de texte rejeter le clavier ou utiliser resignfirstresponder

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch *touch = [touches anyObject];
 if(![touch.view isMemberOfClass:[UITextField class]]) {
     [touch.view endEditing:YES];
 }
}
1
répondu Miguel Monteiro 2016-08-04 18:39:25
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
répondu Subhajit 2018-06-27 18:49:40

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 c'est traduisible en rapide et logique. Il peut être appelé n'importe où dans l'application et cachera le clavier peu importe sur quel VC vous êtes ou quoi que ce soit.

0
répondu AlexKoren 2015-08-29 03:00:30

allez à Type de clavier et sélectionnez Par défaut ou tout ce que vous avez besoin du TextField pour. Alors annulez une méthode appelez ça comme vous voulez je l'appelle habituellement touchingBegins. Voici ce que vous avez oublié d'ajouter

super.touchingBegins(touches, withEvent: event)
 }
0
répondu Katz 2015-08-29 03:19:13

introduisent une reconnaissance de geste de robinet et d'action pour elle.

utiliser le code:

nameofourtextfield .resignfirstresponder()

0
répondu kuni 2016-08-19 10:59:37