Закрийте клавіатуру iOS, торкаючись будь-якого місця за допомогою Swift


407

Я все це шукав, але, здається, не можу його знайти. Я знаю, як відхилити клавіатуру за допомогою, Objective-Cале я поняття не маю, як це зробити за допомогою Swift? Хтось знає?


9
Як ви це робите в Objective-C? Зазвичай це перетворення від одного синтаксису до іншого, а рідко - це різні методи / конвенції.
Крейг Отіс

5
Я не вкопався в Swift, але я був під враженням, що API той самий…
coreyward

Ви можете перевірити цю відповідь .
Ахмад Ф

Відповіді:


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

Ця функція включена в стандартну функцію мого репо, яка містить багато корисних розширень Swift, як ця, перевірте це: https://github.com/goktugyil/EZSwiftExtensions


19
Оскільки Swift 2 у першій відповіді замініть цей рядок-> дозвольте натиснути: UITapGestureRecognizer = UITapGestureRecognizer (ціль: самодіяльність, дія: #selector (MyViewController.dismissKeyboard))
Сем Беллероз

2
він порушує набір tableviewcell на настільному контролері
Utku Dalmaz

11
Це одне з найкорисніших розширень, з яких я коли-небудь стикався! Дякую! Єдине застереження, яке я хотів би сказати, - це може заважати didSelectRowAtIndexPath.
Кліфтон Лабрум

47
Щойно виявив це питання і застосував цей метод. Ця річ із "didSelectRow" tableView / UICollectionView, що не викликає, буквально зводила мене з розуму. Рішення: Просто додайте в ваш додатковий номер : tap.cancelsTouchesInView = false. Це вирішило це для мене принаймні. Сподіваюся, що це комусь допоможе
Quantm

10
"Перевірте мою репо" - це нове "Слухає мою нову мікс-стрічку": P
Josh

118

Відповідь на ваше запитання про те, як відмовити клавіатуру в 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)
    }

}

( Джерело цієї інформації ).


6
Чудовий фрагмент кодексу, дякую! touchchesBegan саме те, що я шукав :)
Лукаш Червінський

4
Це не дуже спрацювало для мене. Якщо я натисніть на перегляд контролера перегляду, він працює. Якщо я натисніть елемент керування у вікні перегляду, клавіатура не відхиляє.
користувач3731622

Це найкраща відповідь, яку я коли-небудь використовував! Цю відповідь слід позначити правильною. Спасибі людино!
wagng

Це найкраще рішення, яке я бачив досі. Невелика примітка: у новіших Swift перепис заміни трохи змінився. Потрібно додати _ перед штрихами: переосмислити функцію дотикуПочаток (_ дотики: Встановити <UITouch>, withEvent подія: UIEvent?)
Regis St-Gelais

1
Це, мабуть, слід позначити як правильне. Поточна прийнята відповідь робить кожну кнопку у вікні невідчутною під час показу клавіатури.
Bartek Spitza

39

Swift 4 працює

Створіть розширення, як показано нижче, і зателефонуйте hideKeyboardWhenTappedAround()у контролер Base view

//
//  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, щоб не потрібно постійно телефонувати у всіх контролерах перегляду.


36

Можна зателефонувати

resignFirstResponder()

у будь-якому екземплярі UIResponder, наприклад UITextField. Якщо ви зателефонуєте до цього виду, який в даний час призводить до відображення клавіатури, клавіатура буде відхилена.


5
У ситуації, коли ви точно не знаєте першого відповідача, resignFirstResponder () може призвести до купи проблем. Відповідь Esq нижче (використовуючи view.doneEditing ()) набагато доречніше
shiser

1
Щоразу, коли я використовую resignFirstResponder на своєму textField, програма виходить з ладу. Я спробував усе, що я міг придумати, і оглянув Інтернет, щоб виправити. Ніщо мені не допомагає. Чи знаєте ви, чому це відбувається?
AugustoQ

1
Як сказав Шизер, це не найкраще рішення. плюс це не працює у всіх ситуаціях.
Алікс

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
    }

}

touchsBegan працював для мене, щоб закінчити редагування текстового поля та перегляду тексту. Спасибі
Санджу,

Це те, що я використовую, просто. Видаліть також непов'язані коди, щоб зосередити увагу на рішенні.
Джон Доу

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
}

але у другому випадку вам також потрібно буде передати делегат від усіх текстових полів ViewController в Main.Storyboard


Я отримую unrecognized selector sent to instanceз цим кодом.
Haring10

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) простіший, оскільки він не вимагає від вас зберігання змінної або припущення, що у вас є лише одне текстове поле.
Глен Хоуз

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
Етан Паркер

Потрібно подивитися на TableView not TextField
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()використовувались (я думаю, це не рідкість), викликаючи проблеми компілятора.

Потім, як зазначено вище, цю поведінку можна включити в окремих контролерах перегляду:

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

7

Якщо ви використовуєте подання прокрутки, це може бути набагато простіше.

Просто виберіть Dismiss interactivelyу раскадровці.


7

У Swift 4 додайте @objc:

У переглядіDidLoad:

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

Щоб розширити відповідь Ескароута , я завжди використовую наступне для відхилення клавіатури, особливо якщо клас, з якого я відхиляю клавіатуру , не має 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

Цей один вкладиш віддає клавіатуру від усіх (будь-яких) UITextField в UIView

self.view.endEditing(true)

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 та скасуйте дотикиBegan.

Швидкий 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

Ви також можете додати розпізнавальник жестів, щоб відкликати клавіатуру. : 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

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

@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() в розпізнавальник жестів (або там, де вам підходить). Недолік - це те, що ви повинні підтримувати список UITextFields, коли ви додаєте або видаляєте поля.

Коментарі вітаються. Якщо є проблема із закликом resignFirstResponder()до елементів управління, які не є першим відгуком, або якщо існує легкий і гарантований невідкладний спосіб відстежити поточного першого респондента, я хотів би почути про це!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.