Swift를 사용하여 어디서나 터치하여 iOS 키보드 닫기


407

나는 이것을 온통 찾고 있었지만 그것을 찾을 수없는 것 같습니다. 키보드를 사용하여 해제하는 방법을 알고 Objective-C있지만 사용 방법을 모릅니다 Swift. 아는 사람 있나요?


9
Objective-C에서 어떻게하고 있습니까? 일반적으로 한 구문에서 다른 구문으로의 변환이며, 다른 방법 / 컨벤션 문제는 거의 없습니다.
Craig Otis 2016 년

5
나는 스위프트 파고하지 않은,하지만 난 ... API가 동일 인상이었다
coreyward

이 답변 을 확인하고 싶을 수도 있습니다 .
Ahmad F

답변:


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

이 기능을 여러 개 사용하려는 경우이 작업을 수행하는 다른 방법이 있습니다 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() 
}

이 기능은 내 repo의 표준 기능으로 포함되어 있으며이 기능과 같은 유용한 스위프트 확장 기능이 많이 포함되어 있습니다. https://github.com/goktugyil/EZSwiftExtensions


19
첫 번째 대답 스위프트 2 이후,하자>이 라인 - 대체 탭 : UITapGestureRecognizer = UITapGestureRecognizer (대상 : 자기 행동 : #selector (MyViewController.dismissKeyboard))
샘 Bellerose

2
그것은 tableviewcontroller에 tableviewcell의 segue를

11
이것은 내가 만난 가장 유용한 확장 중 하나입니다! 감사합니다! 내가 연장 할 유일한주의 사항은 이것이 방해 할 수 있다는 것입니다 didSelectRowAtIndexPath.
Clifton Labrum

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

이것은 내가 지금까지 사용해 본 최고의 답변입니다! 이 답변은 올바른 것으로 표시되어야합니다. 고마워요!
wagng

이것이 내가 지금까지 본 최고의 솔루션입니다. 작은 참고 사항 : 최신 Swift에서는 재정의 서명이 약간 변경되었습니다. 당신은 터치하기 전에 _ 추가해야합니다 touchesBegan FUNC 오버라이드 (_ 터치 : 설정 <UITouch>, withEvent 이벤트 : UIEvent를)
레지스 세인트 Gelais

1
이것은 아마도 올바른 것으로 표시되어야합니다. 현재 허용되는 답변은 키보드가 표시 될 때보기의 모든 버튼이 응답하지 않게합니다.
Bartek Spitza

39

스위프트 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)
    }
}

모든 View Controller에서 항상 호출 할 필요가 없도록 Base View Controller에서 호출하는 것이 가장 중요합니다.


36

전화해도됩니다

resignFirstResponder()

UITextField와 같은 UIResponder의 모든 인스턴스에서 현재 키보드가 표시되는 뷰에서 호출하면 키보드가 사라집니다.


5
첫 번째 응답자를 정확히 모르는 상황에서 resignFirstResponder ()로 인해 많은 문제가 발생할 수 있습니다. 아래의 Esq의 답변 (view.doneEditing () 사용)이 훨씬 더 적합합니다.
shiser

1
textField에서 resignFirstResponder를 사용할 때마다 앱이 중단됩니다. 나는 내가 생각할 수있는 모든 것을 시도하고 웹 주위에서 해결책을 찾았습니다. 아무것도 나를 도와주지 않습니다. 왜 그런 일이 발생하는지 알고 싶습니까?
AugustoQ

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

스위프트 3의 경우 매우 간단합니다.

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

RETURN 키를 눌렀을 때 키보드를 숨기려면

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

그러나 두 번째 경우에는 모든 textFields에서 Main.Storyboard의 ViewController로 대리자를 전달해야합니다.


나는 unrecognized selector sent to instance이 코드를 얻는다 .
Haring10

11

스위프트 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) 호출은 변수를 저장할 필요가 없거나 하나의 텍스트 필드 만 가정한다는 점에서 더 간단합니다.
Glenn Howes

10

대시의 대답은 정확하고 선호됩니다. 보다 "부서진 지구"접근법은 전화하는 것 view.endEditing(true)입니다. 이로 인해 view모든 하위 뷰가 발생 합니다 resignFirstResponder. 해제하려는 뷰에 대한 참조가 없으면 해킹이지만 효과적인 솔루션입니다.

개인적으로 첫 번째 응답자를 사임하려는 관점에 대한 참조가 있어야한다고 생각합니다. .endEditing(force: Bool)야만적 인 접근이다; 사용하지 마십시오.


10

신속한 5 단 두 줄이면 충분합니다. 당신의 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에서 추가 작업을 수행 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

이 하나의 라이너는 UIView의 모든 UITextField에서 Keyboard를 사임합니다.

self.view.endEditing(true)

4

신속하게 사용할 수 있습니다

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

}

3

스위프트 3

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

}

3

viewDidLoad()메소드 의 한 줄의 코드 :

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

2

탭 제스처 인식기를 추가하여 키보드를 사직 할 수도 있습니다. :디

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

또 다른 가능성은 터치해야 할 모든보기 아래에 내용이없는 큰 버튼을 추가하는 것입니다. 다음과 같은 조치를 취하십시오.

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

제스처 인식기의 문제는 나를위한 것이 었습니다.


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() viewcontroller에서 모든 텍스트 필드 를 호출 하는 것 입니다. 다음은 모든 텍스트 필드의 컬렉션을 만드는 예입니다 (제 경우에는 검증 코드에 필요했습니다).

@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.