Swift kullanarak herhangi bir yere dokunarak iOS Klavyesini kapatın


408

Bunun için her yerde bakıyordum ama onu bulamıyorum. Klavyeyi kullanarak nasıl kapatacağımı biliyorum Objective-Cama bunu nasıl yapacağımı bilmiyorum Swift? Kimse biliyor mu?


9
Objective-C'de nasıl yapıyorsun? Normalde bir sözdiziminden diğerine dönüşüm ve nadiren farklı yöntemler / kurallar meselesidir.
Craig Otis

5
Swift'e
girmedim

Bu yanıtı kontrol etmek isteyebilirsiniz .
Ahmad F

Yanıtlar:


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

Bu işlevi birden fazla kullanacaksanız, bu görevi gerçekleştirmenin başka bir yolu 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)
    }
}

Şimdi her UIViewControllerbirinde yapmanız gereken tek şey bu işlevi çağırmaktır:

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

Bu işlev repo'mda bunun gibi birçok yararlı Swift Uzantısı içeren standart bir işlev olarak yer alıyor, bir göz atın: https://github.com/goktugyil/EZSwiftExtensions


19
İlk cevapta Swift 2'den beri, bu satırı değiştirin-> izin verin: UITapGestureRecognizer = UITapGestureRecognizer (hedef: benlik, eylem: #selector (MyViewController.dismissKeyboard))
Sam Bellerose

2
tableviewcell'in sehpasını bir tableviewcontroller'da kırar
Utku Dalmaz

11
Bu şimdiye kadar karşılaştığım en yararlı uzantılardan biri! Teşekkür ederim! Uzatacağım tek dikkat bunun müdahale edebileceğidir didSelectRowAtIndexPath.
Clifton Labrum

47
Sadece bu soruyu keşfetti ve bu yöntemi uyguladı. TableView / UICollectionView "didSelectRow" ile o şey tam anlamıyla çağırmak değil beni deli etti. Çözümdür: Basitçe uzantısı bu ekleyin: tap.cancelsTouchesInView = false. En azından benim için çözdü. Umarım bu birine yardımcı olur
Quantm

10
"Benim repo göz atın" yeni "Hears benim yeni mixtape": P
Josh

118

Aşağıdaki Swift'i kullanarak Xcode 6.1'de klavyenin nasıl kapatılacağı ile ilgili sorunuzun cevabı:

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

}

( Bu bilgilerin kaynağı ).


6
Harika bir kod parçası, teşekkürler! Began tam olarak aradığım şeydi :)
Lukasz Czerwinski

4
Bu benim için pek işe yaramadı. Görünüm denetleyicisinin görünümüne dokunursam çalışır. Görünümdeki bir kontrol öğesine dokunursam, klavye kapanmaz.
user3731622

Bu şimdiye kadar kullandığım en iyi cevap! Bu cevap doğru olarak işaretlenmelidir. Teşekkürler dostum!
wagng

Bu şimdiye kadar gördüğüm en iyi çözüm. Küçük not: daha yeni Swift'te geçersiz kılma imzası biraz değişti. Dokunmadan önce _ eklemeniz gerekir: func dokunuşlarını geçersiz kılBegan (_ dokunur: <UITouch>, ileEt olayı ayarla: UIEvent?)
Regis St-Gelais

1
Bu muhtemelen doğru olarak işaretlenmelidir. Kabul edilen geçerli cevap, klavye gösterilirken görünümdeki her düğmenin yanıt vermemesine neden olur.
Bartek Spitza

39

Swift 4 çalışma

Aşağıdaki gibi uzantı oluşturun hideKeyboardWhenTappedAround()ve Temel görünüm denetleyicinizi arayın .

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

Base View Controller'ınızda aramak için en önemli şey, böylece tüm view kontrolörlerinde her zaman aramanıza gerek kalmaz.


36

Arayabilirsin

resignFirstResponder()

UITextField gibi herhangi bir UIResponder örneğinde. Klavyenin görüntülenmesine neden olan görünümde çağırırsanız, klavye kapanacaktır.


5
İlk yanıtlayıcıyı tam olarak bilmediğiniz bir durumda, resignFirstResponder () bir sorun yığınına yol açabilir. Esq'in aşağıdaki cevabı (view.doneEditing () kullanarak) çok daha uygun
shiser

1
Ne zaman benim textField üzerinde resignFirstResponder kullandığınızda uygulama çöküyor. Aklıma gelen her şeyi denedim ve düzeltmek için web'e baktım. Bana hiçbir şey yardım etmiyor. Bunun neden olduğunu biliyor musun?
AugustoQ

1
Shiser'ın dediği gibi bu en iyi çözüm değil. artı her durumda çalışmaz.
Alix

21
//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
    }

}

Metin alanı ve metin görünümünü düzenlemeyi sona erdirmek benim için çalıştı. Teşekkürler
Sanju

Kullandığım şey bu, basit. Çözüme odaklanmak için ilgisiz kodları da kaldırın.
John Doe

19

Swift 3 için çok basit

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

RETURN tuşuna basarken klavyeyi gizlemek istiyorsanız

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

ancak ikinci durumda, tüm textField'lerden Temsilciyi Main.Storyboard'daki ViewController'a iletmeniz gerekir.


unrecognized selector sent to instanceBu kodu alıyorum .
Haring10

11

Swift 3: Klavyeyi kapatmanın en kolay yolu:

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

1
View.endEditing (true) çağrısının, bir değişkeni depolamanızı veya yalnızca bir metin alanınız olduğunu varsaymanızı gerektirmediği için oldukça eminim.
Glenn Howes

10

Dash'in yanıtı doğru ve tercih edilir. Daha "yakılmış toprak" yaklaşımını çağırmak view.endEditing(true). Bu neden olur viewve tüm alt görünümleri resignFirstResponder. Çıkarmak istediğiniz görünüme referansınız yoksa, bu hileli ama etkili bir çözümdür.

Şahsen ben ilk istifaya istifa etmek istediğiniz görünümü bir referans olması gerektiğini düşünüyorum. .endEditing(force: Bool)barbarca bir yaklaşımdır; lütfen kullanma.


10

hızlı 5 sadece iki satır yeterlidir. İşinize ekleyin viewDidLoad.

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

Dokunma hareketiniz başka dokunuşları engellediyse, bu satırı ekleyin:

tapGesture.cancelsTouchesInView = false

Çok basit ve zarif bir çözüm :), burada cevap olmalı.
Joseph Astrahan

9

Film şeridinde:

  1. TableView'ı seçin
  2. sağ taraftan, özellik denetçisini seçin
  3. klavye bölümünde - istediğiniz kapatma modunu seçin

bu öğeyi bulamıyor, nerede ve neye benziyor? Bir metnin nitelik denetçisiyim
Ethan Parker

TableView TextField değil bakmak gerekir
zevij

9

Hızlı 3:

SelectorKapat işlevinde ek şeyler yapabilmek cancelsTouchesInViewve görünümün diğer öğelerine dokunmayla bozulmayı önlemek için parametre olarak genişletme .

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

Kullanımı:

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

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

9

Kolay çözmenize yardımcı olacak IQKeyboardmanager kullanın .....

/////////////////////////////////////////

! [klavyeyi devre dışı bırakma ..] [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

En iyi çözümün bazı düzenlemelerle @Esqarrouth'un kabul ettiği cevabı içerdiğini gördüm:

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

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

Çizgi tap.cancelsTouchesInView = falsekritikti: UITapGestureRecognizergörünümdeki diğer öğelerin kullanıcı etkileşimi almasını engellememesini sağlar .

Yöntem dismissKeyboard()biraz daha az zarif olarak değiştirildi dismissKeyboardView(). Bunun nedeni, projemin oldukça eski kod tabanında, dismissKeyboard()derleyici sorunlarına neden olan çok sayıda kez kullanıldığını (bunun nadir olmadığını hayal ediyorum) vardı.

Daha sonra, yukarıdaki gibi, bu davranış bireysel Görünüm Denetleyicilerinde etkinleştirilebilir:

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

7

Kaydırma görünümü kullanırsanız, çok daha basit olabilir.

Sadece Dismiss interactivelyfilm şeridinde seçin .


7

Swift 4'te @objc ekleyin:

ViewDidLoad içinde:

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

İşlev:

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

7

Bu uzantıyı ViewController'ınıza ekleyin:

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

6

Esqarrouth'un cevabını genişletmek için , özellikle klavyeyi çıkardığım sınıfın bir viewözelliği yoksa ve / veya bir altUIView sınıfı değilse, klavyeyi kapatmak için aşağıdakileri her zaman kullanırım .

UIApplication.shared.keyWindow?.endEditing(true)

Ve kolaylık sağlamak için, UIApplcationsınıfa aşağıdaki uzantı :

extension UIApplication {

    /// Dismisses the keyboard from the key window of the
    /// shared application instance.
    ///
    /// - Parameters:
    ///     - force: specify `true` to force first responder to resign.
    open class func endEditing(_ force: Bool = false) {
        shared.endEditing(force)
    }

    /// Dismisses the keyboard from the key window of this 
    /// application instance.
    ///
    /// - Parameters:
    ///     - force: specify `true` to force first responder to resign.
    open func endEditing(_ force: Bool = false) {
        keyWindow?.endEditing(force)
    }

}

5
  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

Acemi bir programcı olarak, insanlar daha yetenekli ve gereksiz yanıtlar ürettiklerinde kafa karıştırıcı olabilir ... Yukarıda gösterilen karmaşık şeylerden hiçbirini yapmanız gerekmez! ...

İşte en basit seçenek ... Klavyenizin metin alanına yanıt olarak görünmesi durumunda - Dokunmatik ekran işlevinizin içine resignFirstResponder işlevini eklemeniz yeterlidir . Aşağıda gösterildiği gibi - İlk Yanıtlayıcı serbest bırakıldığından (Yanıtlayıcı zincirinden çıkarken) klavye kapanacaktır ...

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

5

Klavye için IQKeyBoardManagerSwift kullanıyorum. kullanımı kolaydır. sadece 'IQKeyboardManagerSwift' bölmesini ekleyin

IQKeyboardManagerSwift'i içe aktarın ve üzerine kod didFinishLaunchingWithOptionsyazın AppDelegate.

///add this line 
IQKeyboardManager.shared.shouldResignOnTouchOutside = true
IQKeyboardManager.shared.enable = true

4

Bu bir astar, bir UIView'deki UITextField öğesinin tümünden (herhangi birinden) Klavye'yi istifa

self.view.endEditing(true)

4

viewDidLoad()Yöntemde sadece bir kod satırı :

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

4

Hızlıca kullanabilirsiniz

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

}

3

Swift3 için

Bir olay tanıyıcısını viewDidLoad'a kaydettirin

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

o zaman hareketi aynı viewDidLoad öğesinde görünüme eklememiz gerekir.

self.view.addGestureRecognizer(tap)

Sonra kayıtlı yöntemi başlatmamız gerekiyor

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

1
Cevabın tamamı ve notları için teşekkürler. Benim için işe yarayan tek çözüm bu.
zeeshan

3

@ King-Wizard'ın cevabını düzenlememden bu yana yeni bir yanıt olarak yayınlanıyor.

Sınıfınızı UITextField temsilcisine dönüştürün ve touch'ları geçersiz kılın.

Hızlı 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)
    }

}

2

Klavyeyi bırakmak için bir dokunma hareketi tanıyıcı da ekleyebilirsiniz. : D

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

2

Başka bir olasılık, dokunmanız gerekebilecek tüm görünümlerin altında yer alan hiçbir içeriği olmayan büyük bir düğme eklemektir. Ona bir işlem verin:

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

Bir jest tanıyıcı ile ilgili sorun benim için oldu, ayrıca tableViewCells tarafından almak istediğim tüm dokunuşları yakaladı.


2

Teması da alması gereken başka görünümleriniz varsa, cancelsTouchesInView = false

Bunun gibi:

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

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

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

}

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

Şunu deneyin, Çalışıyor


1

Görünümde birden fazla metin alanı olduğunda

Arama yapmamak için @ modocache'nin önerisini takip etmekview.endEditing() , ilk yanıtlayan metin alanını takip edebilirsiniz, ancak bu dağınık ve hataya yatkındır.

Alternatif olarak resignFirstResponder() , görünüm denetleyicisindeki tüm metin alanlarını çağırmak mümkündür . İşte tüm metin alanlarının (bu durumda doğrulama kodu için gerekli olan) bir koleksiyon oluşturma örneği:

@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]
}

Mevcut koleksiyonla, hepsini yinelemek basit bir konudur:

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

Böylece dismissKeyboard()jest tanımlayıcınızı (veya sizin için uygun olan her yerde) arayabilirsiniz . Dezavantajı, UITextFieldalan eklediğinizde veya kaldırdığınızda s listesini korumanız gerektiğidir .

Yorumlarınızı bekliyoruz. resignFirstResponder()İlk yanıtlayıcı olmayan denetimleri çağırmayla ilgili bir sorun varsa veya geçerli ilk yanıtlayıcıyı izlemenin kolay ve garantili buggy olmayan bir yolu varsa, bunu duymak isterim!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.