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
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
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)
}
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()
}
}
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.
swift 3
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
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
}
}
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)
}
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)
}
Pour Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
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 !
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];
}
}
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
}
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.
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)
}
introduisent une reconnaissance de geste de robinet et d'action pour elle.
utiliser le code:
nameofourtextfield .resignfirstresponder()