Закройте клавиатуру iOS, коснувшись любого места с помощью Swift

Я искал это повсюду, но я не могу его найти. Я знаю, как отклонить клавиатуру с помощью Objective-C но я понятия не имею, как это сделать с помощью Swift? Кто-нибудь знает?

30 ответов


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


ответ на ваш вопрос о том, как отклонить клавиатуру в Xcode 6.1 с помощью Swift ниже:

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

}

(источник информации).


можно назвать

resignFirstResponder()

на любом экземпляре UIResponder, например UITextField. Если вы вызываете его в представлении, которое в настоящее время вызывает отображение клавиатуры, клавиатура будет отклонена.


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

}

для Swift 3 это очень просто

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

Если вы хотите скрыть клавиатуру при нажатии клавиши возврата

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

но во втором случае вам также нужно будет передать делегат из всех текстовых полей в ViewController в основном.Раскадровка


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
    }

Swift 4 работает

создать расширение, как показано ниже & call 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.endEditing(true). Это вызывает view и все его подвиды в resignFirstResponder. Если у вас нет ссылки на представление, которое вы хотели бы отклонить, это хакерское, но эффективное решение.

обратите внимание, что лично я думаю, что вы должны иметь ссылку на мнение, которое вы хотели бы отправить в отставку первым ответчиком. .endEditing(force: Bool) - это варварский подход; пожалуйста, не используйте его.


в раскадровке:

  1. выберите TableView
  2. С правой стороны, выберите инспектор атрибут
  3. В разделе клавиатуры-выберите режим увольнения, который вы хотите

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

![ как отключить клавиатуру..][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)
  }
}

Если вы используете вид прокрутки, это может быть намного проще.

выберите Dismiss interactively в раскадровке.


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

этот один лайнер покидает клавиатуру из всех (любых) UITextField в UIView

self.view.endEditing(true)

Я нашел лучшее решение, включающее принятый ответ от @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() уже использовался (я полагаю, это не uncommon), вызывая проблемы с компилятором.

тогда, как и выше, это поведение может быть включено в отдельных контроллерах вида:

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

как начинающий программист это может быть запутанным, когда люди производят более квалифицированные и ненужные ответы...Вам не нужно делать какие-либо сложные вещи, показанные выше!...

вот самый простой вариант...в случае, если ваша клавиатура появляется в ответ на текстовое поле-внутри функции сенсорного экрана просто добавьте resignFirstResponder


Для Swift3

зарегистрировать распознаватель событий в viewDidLoad

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

затем нам нужно добавить жест в представление в том же viewDidLoad.

self.view.addGestureRecognizer(tap)

тогда нам нужно инициализировать зарегистрированный метод

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

строить из правильный ответ Я всегда использую следующее расширение:

extension UIApplication {
    /// Dismiss keyboard from key window.
    open static func endEditing(_ force: Bool = false) {
        shared.keyWindow?.endEditing(force)
    }
}

таким образом, если класс, в котором я пытаюсь отменить редактирование, не имеет view свойство или не является подклассом UIView Я могу просто позвонить UIApplication.endEditing().


вы также можете добавить распознаватель жестов крана, чтобы отказаться от клавиатуры. : 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")
}

другая возможность-просто добавить большую кнопку без содержимого, которое лежит под всеми видами, которые вам могут понадобиться коснуться. Дайте ему действие с именем:

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

проблема с распознавателем жестов была для меня, что он также поймал все прикосновения, которые я хотел получить от tableViewCells.


Если у вас есть другие виды, которые должны получить прикосновение, а вы должны установить cancelsTouchesInView = false

такой:

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

override func viewDidLoad() {
        super.viewDidLoad()

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

}

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

попробуйте это, он работает


в Swift 4 Добавьте @objc:

в viewDidLoad:

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

функция:

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

добавьте это расширение в свой 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)
}
}

когда есть более одного текстового поля в представлении

соблюдать рекомендация@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() в вашем распознавателе жестов (или там, где это подходит для вас). Недостатком является то, что вы должны вести список UITextFields при добавлении или удалении полей.

комментарии приветствуются. Если есть проблема с вызовом resignFirstResponder() на элементах управления, которые не являются первым ответчиком, или если есть простой и гарантированный не багги способ отслеживания текущего первого ответчика, я хотел бы услышать об этом!


Я работал на uisearchbar . Смотри мой.

import UIKit

class BidderPage: UIViewController,UISearchBarDelegate,UITableViewDataSource {

     let recognizer = UITapGestureRecognizer()

// Set recogniser as public in case of tableview and didselectindexpath.


    func searchBarTextDidBeginEditing(searchBar: UISearchBar)

    {

        recognizer.addTarget(self, action: "handleTap:")
        view.addGestureRecognizer(recognizer)

    }

    func handleTap(recognizer: UITapGestureRecognizer) {
        biddersearchbar .resignFirstResponder()
    }
    func searchBarTextDidEndEditing(searchBar: UISearchBar)
    {
        view .removeGestureRecognizer(recognizer)

    }

Я предпочитаю этот шутка:

view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "dismissKeyboardFromView:"))

просто поместите это в функцию override viewDidLoad в любом подклассе UIViewController, который вы хотите, чтобы это произошло, а затем поместите следующий код в новый пустой файл в вашем проекте под названием "UIViewController+dismissKeyboard.swift":

import UIKit

extension UIViewController {
    // This function is called when the tap is recognized
    func dismissKeyboardFromView(sender: UITapGestureRecognizer?) {
        let view = sender?.view
        view?.endEditing(true)
    }
}

Я достал тебя fam

override func viewDidLoad() {
    super.viewDidLoad() /*This ensures that our view loaded*/
    self.textField.delegate = self /*we select our text field that we want*/   
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: Selector("dismissKeyboard")))
}

func dismissKeyboard(){ /*this is a void function*/
    textField.resignFirstResponder() /*This will dismiss our keyboard on tap*/
}

Я нашел простое решение: 1. Добавьте UITapGestureRecognizer в контроллер вида 2. Добавьте IBAction в свой UITapGestureRecognizer 3. Наконец, вы можете подать в отставку первый ответчик

class ViewController: UIViewController
{

@IBOutlet var tap: UITapGestureRecognizer!
@IBOutlet weak var label: UILabel!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad()
{
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}


@IBAction func dismissUsingGesture(_ sender: UITapGestureRecognizer)
{
   self.textField.resignFirstResponder()
    label.text = textField.text!
}
}

вот краткий способ сделать это:

let endEditingTapGesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:)))
endEditingTapGesture.cancelsTouchesInView = false
view.addGestureRecognizer(endEditingTapGesture)