ChatGPT解决这个技术问题 Extra ChatGPT

使用 Swift 通过触摸任意位置来关闭 iOS 键盘

我一直在寻找这个,但我似乎找不到它。我知道如何使用 Objective-C 关闭键盘,但我不知道如何使用 Swift 来关闭键盘?有人知道吗?

你在 Objective-C 中是怎么做的?它通常是从一种语法到另一种语法的转换,很少涉及不同的方法/约定。
您可能需要检查 this answer

s
spacecash21
override func viewDidLoad() {
    super.viewDidLoad()
          
    //Looks for single or multiple taps. 
     let tap = UITapGestureRecognizer(target: self, action: #selector(UIInputViewController.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(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 中,其中包含很多有用的 Swift 扩展,比如这个,检查一下:https://github.com/goktugyil/EZSwiftExtensions


由于 Swift 2 在第一个答案中,替换此行->让点击: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyViewController.dismissKeyboard))
它打破了 tableviewcell 在 tableviewcontroller 上的 segue
这是我遇到过的最有用的扩展之一!谢谢!我要提出的唯一警告是这可能会干扰 didSelectRowAtIndexPath
刚刚发现了这个问题并实现了那个方法。 tableView/UICollectionView 的“didSelectRow”没有真正调用的那个东西让我发疯了。解决方案是:只需将其添加到您的扩展程序:tap.cancelsTouchesInView = false。这至少为我解决了。希望这可以帮助某人
这个答案有问题,我在视图中有一个按钮,我想在其中执行此操作,当键盘启动并单击按钮时,键盘将消失但我不会获得完整的按钮操作,有些奇怪行为
c
crazy_phage

关于如何使用 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)
    }

}

(Source of this information)。


很棒的一段代码,谢谢! touchesBegan 正是我想要的:)
这对我来说不太奏效。如果我点击视图控制器的视图,它就可以工作。如果我点击视图中的控件项,键盘不会关闭。
这是迄今为止我见过的最好的解决方案。小提示:在较新的 Swift 中,覆盖签名发生了一些变化。您需要在触摸之前添加 _:覆盖 func touchesBegan(_ touches: Set, withEvent event: UIEvent?)
这可能应该被标记为正确的。当前接受的答案使视图中的每个按钮在显示键盘时都没有响应。
在 tableview 或任何可滚动的内部点击时,这不起作用。
F
Fahim Parkar

斯威夫特 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)
    }
}

在您的基本视图控制器中调用最重要的事情,这样就无需在所有视图控制器中一直调用。


D
Dash

你可以打电话

resignFirstResponder()

在 UIResponder 的任何实例上,例如 UITextField。如果您在当前导致键盘显示的视图上调用它,则键盘将关闭。


在您不完全了解第一响应者的情况下, resignFirstResponder() 可能会导致一堆麻烦。 Esq 在下面的回答(使用 view.doneEditing())更合适
每当我在我的 textField 上使用 resignFirstResponder 时,应用程序就会崩溃。我尝试了我能想到的一切,并在网上寻找解决办法。没有什么能帮到我。你会碰巧知道为什么会这样吗?
正如shiser所说,这不是最好的解决方案。此外,它并非在所有情况下都有效。
W
William Hu

swift 5 两行就够了。添加到您的 viewDidLoad 中应该可以工作。

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

如果您的点击手势阻止了其他一些触摸,请添加以下行:

tapGesture.cancelsTouchesInView = false

Y
Yerbol

对于 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
}

但在第二种情况下,您还需要将所有文本字段的委托传递给 Main.Storyboard 中的 ViewController


我使用此代码得到 unrecognized selector sent to instance
N
Naishta
//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
    }

}

N
NikaE

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
    }

我相当确定 view.endEditing(true) 调用更简单,因为它不需要您存储变量或假设您只有一个文本字段。
A
Artem

viewDidLoad() 方法中只有一行代码:

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

谢谢,这有诀窍。但是作为一个在 Android 上开始应用程序开发然后也开始为 iOS 开发应用程序的人,我总是惊讶于这不是默认行为,因为与 Android 不同,用户无法关闭键盘,否则应用程序是有效锁定!
P
Pramodya Abeysinghe

迅速你可以使用

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

}

m
modocache

Dash 的答案是正确且首选的。更“焦土”的方法是调用 view.endEditing(true)。这会导致 view 及其所有子视图变为 resignFirstResponder。如果您没有对要忽略的视图的引用,这是一个 hacky 但有效的解决方案。

请注意,我个人认为您应该参考您希望让第一响应者辞职的观点。 .endEditing(force: Bool) 是一种野蛮的做法;请不要使用它。


L
Luke Harries

我发现最好的解决方案包括@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() 
}

z
zevij

在故事板中:

从右侧选择 TableView,在键盘部分选择属性检查器 - 选择您想要的关闭模式


找不到那个项目,它在哪里,它看起来像什么?我在 textField 的属性检查器中
您需要查看 TableView 而不是 TextField
D
David Seek

斯威夫特 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
}

N
NoodleOfDeath

为了扩展 Esqarrouth's answer,我总是使用以下方法来关闭键盘,特别是如果我要关闭键盘的类没有 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)
    }

}

H
Hardik Bar

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

J
JIE WANG

如果您使用滚动视图,它可能会简单得多。

https://i.stack.imgur.com/NblEs.png

只需在情节提要中选择 Dismiss interactively


J
Jarvis The Avenger

将此扩展添加到您的 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)
  }
}

V
Vaisakh KP

我已经使用 IQKeyBoardManagerSwift 作为键盘。它很容易使用。只需添加 pod 'IQKeyboardManagerSwift'

导入 IQKeyboardManagerSwift 并在 AppDelegate 中的 didFinishLaunchingWithOptions 上编写代码。

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

u
user3856297

在 Swift 4 中,添加@objc:

在 viewDidLoad 中:

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

功能:

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

P
Prashant chaudhary
  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)
  }
}

I
Ingo Karkat

作为一个新手程序员,当人们产生更熟练和不必要的响应时可能会感到困惑......你不必做上面显示的任何复杂的事情!......

这是最简单的选项...如果您的键盘出现以响应文本字段 - 在您的触摸屏功能内,只需添加 resignFirstResponder 功能。如下图 - 键盘将关闭,因为 First Responder 被释放(退出 Responder 链)...

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

C
Codetard

这一个班轮从 UIView 中的所有(任何)UITextField 中退出键盘

self.view.endEditing(true)

V
Viktor Sec

自从我编辑@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)
    }

}

S
Sandu

对于 Swift3

在 viewDidLoad 中注册一个事件识别器

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

然后我们需要将手势添加到同一 viewDidLoad 中的视图中。

self.view.addGestureRecognizer(tap)

然后我们需要初始化注册的方法

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

J
Joshua Dance

这是使用 Swift 5 在 2 行中通过点击其他任何位置来关闭键盘的方法。

(我讨厌添加另一个答案,但由于这是 Google 上的最高结果,我会帮助像我这样的新手。)

在您的 ViewController.swift 中,找到 viewDidLoad() 函数。

添加这两行:

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

C
Codetard

您还可以添加轻击手势识别器来退出键盘。 :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")
}

T
Timm Kent

另一种可能性是简单地添加一个没有内容的大按钮,该按钮位于您可能需要触摸的所有视图下方。给它一个名为:

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

手势识别器的问题在于我,它还捕获了我想通过 tableViewCells 接收的所有触摸。


p
ph1lb4

如果您还有其他应接收触摸的视图,则必须设置 cancelsTouchesInView = false

像这样:

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

R
Ramprasath Selvam
override func viewDidLoad() {
        super.viewDidLoad()

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

}

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

试试这个,它的工作