Swiftを使用してどこかにタッチしてiOSキーボードを閉じる


409

私はこれを探し回っていましたが、見つけられないようです。私はキーボードを使用して閉じる方法を知っObjective-Cていますが、それを使用してそれを行う方法がわかりませSwiftんか?誰か知っていますか?


9
Objective-Cではどのようにしていますか?これは通常、1つの構文から別の構文への変換であり、めったに異なるメソッド/規則の問題ではありません。
Craig Otis

5
私は、スウィフトに掘っていないが、私はAPIが同じである印象の下にあった...
coreyward

この答えを確認することをお勧めします
Ahmad F

回答:


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

この機能を複数で使用する場合に、このタスクを実行する別の方法を次に示します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)
    }
}

すべてUIViewControllerので、この関数を呼び出すだけです。

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

この関数は、次のような便利なSwift拡張機能を多く含むレポジトリの標準関数として含まれています。https//github.com/goktugyil/EZSwiftExtensionsを確認してください。


19
最初の回答のSwift 2なので、次の行を置き換えます。->タップを許可:UITapGestureRecognizer = UITapGestureRecognizer(target:self、action:#selector(MyViewController.dismissKeyboard))
Sam

2
それはtableviewcontrollerでtableviewcellのセグエを壊します
Utku Dalmaz

11
これは、私が出会った中で最も役立つ拡張機能の1つです。ありがとうございました!私が拡張する唯一の注意は、これがに干渉する可能性があることdidSelectRowAtIndexPathです。
Clifton Labrum 16

47
この質問を発見し、その方法を実装しました。tableView / UICollectionViewの「didSelectRow」が文字どおりに呼び出されないことは、私を夢中にさせました。解決策は、これを拡張機能に追加するだけですtap.cancelsTouchesInView = false。少なくとも私にとってはそれで解決しました。これが誰かの役に立つことを願っています
Quantm

10
「私のリポジトリをチェックしてください」は新しい「新しいミックステープを聞く」です:P
Josh

118

以下のSwiftを使用してXcode 6.1でキーボードを閉じる方法に関する質問への回答:

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

}

この情報の出典)。


6
素晴らしいコード、ありがとう!touchesBeganはまさに私が探していたものでした:)
Lukasz Czerwinski

4
これではうまくいきませんでした。ビューコントローラーのビューをタップすると機能します。ビューのコントロール項目をタップしても、キーボードが閉じません。
user3731622

これは私がこれまでに使った中で最高の答えです!この回答は正解としてマークする必要があります。ありがとう!
2017年

これは、これまでに見た中で最高のソリューションです。小さなメモ:新しいSwiftでは、オーバーライドの署名が少し変更されました。タッチの前に_を追加する必要があります:func touchesBegan(_ touches:Set <UITouch>、withEvent event:UIEvent?)をオーバーライドします
Regis St-Gelais

1
これはおそらく正しいものとしてマークされているはずです。現在受け入れられている回答では、キーボードが表示されているときにビューのすべてのボタンが反応しなくなります。
Bartek Spitza

39

Swift 4の動作

以下のように拡張機能を作成hideKeyboardWhenTappedAround()し、ベースビューコントローラーで呼び出します。

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

すべてのビューコントローラーで常に呼び出す必要がないように、ベースビューコントローラーで呼び出すことが最も重要です。


36

電話できます

resignFirstResponder()

UITextFieldなどのUIResponderの任意のインスタンス。現在キーボードが表示されているビューで呼び出すと、キーボードが非表示になります。


5
最初のレスポンダが正確にわからない状況では、resignFirstResponder()が大量のトラブルを引き起こす可能性があります。以下のEsqの回答(view.doneEditing()を使用)の方がはるかに適切です
shiser

1
textFieldでresignFirstResponderを使用すると、アプリがクラッシュします。私は思いつく限りのことをすべて試し、修正のためにWebを見回しました。何の助けにもなりません。なぜそれが起こるのか知っていますか?
AugustoQ 2015

1
shiserが言ったように、これは最良の解決策ではありません。さらに、すべての状況で機能するわけではありません。
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
    }

}

touchesBeganは、テキストフィールドとテキストビューの編集を終了するために私のために働きました。ありがとう
Sanju

これは私が使うもので、シンプルです。無関係なコードも削除して、ソリューションに焦点を当てます。
John Doe

19

Swift 3の場合、それは非常に簡単です

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

RETURNキーを押したときにキーボードを非表示にする場合

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

ただし、2番目のケースでは、すべてのtextFieldからMain.StoryboardのViewControllerにデリゲートを渡す必要もあります。


unrecognized selector sent to instanceはこのコードで取得します。
Haring10 2016

11

Swift 3:キーボードを閉じる最も簡単な方法:

  //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)の呼び出しは、変数を格納する必要がないか、テキストフィールドが1つだけであると想定する必要がないため、より単純であると確信しています。
Glenn Howes

10

ダッシュの答えは正しく、優先されます。より「焦土」アプローチはを呼び出すことview.endEditing(true)です。これによりview、そのすべてのサブビューがになりresignFirstResponderます。却下したいビューへの参照がない場合、これは面倒ですが効果的な解決策です。

個人的には、ファーストレスポンダを辞任させたいビューへの参照が必要だと思います。.endEditing(force: Bool)野蛮なアプローチです。使用しないでください。


10

Swift 5は2行で十分です。あなたのviewDidLoad仕事に追加してください。

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

タップジェスチャーが他のタッチをブロックした場合は、次の行を追加します。

tapGesture.cancelsTouchesInView = false

非常にシンプルでエレガントなソリューション:)、ここでの答えになるはずです。
ジョセフアストラハン

9

ストーリーボード:

  1. TableViewを選択します
  2. 右側から、属性インスペクターを選択します
  3. キーボードセクションで-必要な終了モードを選択します

そのアイテムが見つからない場合、それはどこにあり、どのように見えますか?私はtextFieldの属性インスペクタにいます
Ethan Parker

TextFieldではなくTableViewを確認する必要があります
zevij

9

スウィフト3:

Selectorパラメータとしての拡張機能により、dismiss関数で追加の処理を行うことができcancelsTouchesInView、ビューの他の要素へのタッチによる歪みを防ぐことができます。

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

使用法:

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

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

9

IQKeyboardmanagerを使用すると、簡単に解決できます。

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

![キーボードを無効にする方法..] [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

私は最良の解決策として、@ Esqarrouthからの承認済みの回答にいくつかの調整を加えて見つけました。

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

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

この線tap.cancelsTouchesInView = falseは非常に重要でした。これによりUITapGestureRecognizer、ビュー上の他の要素がユーザーの操作を受け取らないようになります。

方法dismissKeyboard()が少しエレガントに変更されましたdismissKeyboardView()。これは、私のプロジェクトのかなり古いコードベースでdismissKeyboard()は、すでに使用されていることが何度もあったため(これは珍しいことではないと思います)、コンパイラーの問題を引き起こしています。

次に、上記のように、この動作を個々のView Controllerで有効にすることができます。

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

7

スクロールビューを使用すると、はるかに簡単になります。

Dismiss interactivelyストーリーボードで選択するだけです。


7

Swift 4で、@ objcを追加します。

viewDidLoadで:

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

関数:

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

7

この拡張機能を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)
  }
}

6

展開するにはEsqarrouthの答え、私はいつも、私はキーボードを却下していたから、クラスが場合は特に、キーボードを閉じ、次を使用していないviewプロパティを、および/またはのサブクラスではありませんUIView

UIApplication.shared.keyWindow?.endEditing(true)

そして、便宜上、UIApplcationクラスへの次の拡張:

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

初心者のプログラマーとして、人々がより熟練した不必要な応答を生成すると混乱する可能性があります...上記の複雑なことをする必要はありません!...

これが最も簡単なオプションです...キーボードがテキストフィールドに応答して表示される場合-タッチスクリーン関数の内部にresignFirstResponder関数を追加するだけです。以下に示すように、最初のレスポンダーが解放されたためにキーボードが閉じます(レスポンダーチェーンを終了します)...

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

5

キーボードにIQKeyBoardManagerSwiftを使用しています。使い方は簡単です。ポッド「IQKeyboardManagerSwift」を追加するだけです

IQKeyboardManagerSwiftをインポートしてdidFinishLaunchingWithOptions、でコードを記述しますAppDelegate

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

4

この1つのライナーは、UIViewのすべてのUITextFieldからキーボードを辞任します。

self.view.endEditing(true)

4

viewDidLoad()メソッド内の1行のコードのみ:

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

4

迅速に使用できます

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

}

3

Swift3の場合

イベント認識機能をviewDidLoadに登録します。

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

次に、同じviewDidLoadのビューにジェスチャーを追加する必要があります。

self.view.addGestureRecognizer(tap)

次に、登録したメソッドを初期化する必要があります

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

1
完全な回答とメモをありがとう。これは私のために働いた唯一の解決策です。
Zeeshan

3

@ King-Wizardの回答の編集が拒否されたため、新しい回答として投稿しました。

クラスをUITextFieldのデリゲートにし、touchesBeganをオーバーライドします。

スウィフト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

キーボードを辞任するために、タップジェスチャー認識機能を追加することもできます。: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

もう1つの可能性は、タッチする必要のあるすべてのビューの下にあるコンテンツのない大きなボタンを追加することです。次の名前のアクションを実行します。

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

ジェスチャレコグナイザの問題は、tableViewCellsで受け取りたいすべてのタッチをキャッチすることでした。


2

タッチを受ける他のビューがある場合は、設定する必要があります cancelsTouchesInView = false

このような:

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

これを試してみてください


1

ビューに複数のテキストフィールドがある場合

@modocacheの推奨に従い、呼び出しを回避するにはview.endEditing()、をにするには、最初のレスポンダーになったテキストフィールドを追跡できますが、これは面倒でエラーが発生しやすくなります。

別の方法resignFirstResponder() として、ビューコントローラのすべてのテキストフィールドを呼び出すこともできます。すべてのテキストフィールドのコレクションを作成する例を次に示します(私の場合は、とにかく検証コードに必要でした)。

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

コレクションを利用できるので、すべてのコレクションを繰り返すのは簡単です。

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

これdismissKeyboard()で、ジェスチャレコグナイザ(または適切な場所)を呼び出すことができます。欠点は、UITextFieldフィールドを追加または削除するときにのリストを維持する必要があることです。

コメントを歓迎します。resignFirstResponder()ファーストレスポンダーではないコントロールの呼び出しに問題がある場合、または現在のファーストレスポンダーを追跡するための簡単で保証されたバグのない方法がある場合は、ぜひお知らせください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.