ios 触摸 UITextField 之外的任何地方时如何关闭键盘(快速)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32281651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:26:10  来源:igfitidea点击:

How to dismiss keyboard when touching anywhere outside UITextField (in swift)?

iosswiftuitextfielduikeyboard

提问by White Hat

I'm working on a project that have a UIViewController, on the view controller there is a UIScrollView and a UITextField on the scrollview. like this: I'm trying to dismiss the keyboard and hide it after typing some text in the textfield and tap anywhere outside the textfield. I've tried the following code:

我正在处理一个有 UIViewController 的项目,在视图控制器上,滚动视图上有一个 UIScrollView 和一个 UITextField。像这样: 我试图在文本字段中输入一些文本并点击文本字段外的任何地方后关闭键盘并隐藏它。我试过以下代码:

override func viewDidLoad() {
    super.viewDidLoad()
    self.textField.delegate = self;
}

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

It works for me when I tap outside the scrollview, but when I tap on the scrollview nothing happens and the keyboard doesn't hide.

当我点击滚动视图外部时它对我有用,但是当我点击滚动视图时没有任何反应并且键盘不会隐藏。

Is there any way to dismiss the keyboard when tapping anywhereoutside the textfield? thanks

当点击文本字段外的任何地方时,有没有办法关闭键盘?谢谢

回答by Matthew Bradshaw

Edited for Swift 4

为 Swift 4 编辑

Edit: Added @objc. While this isn't the best option for performance, one instance of it here shouldn't cause too many problems until there is a better solution.

编辑:添加@objc. 虽然这不是性能的最佳选择,但在有更好的解决方案之前,这里的一个实例不应引起太多问题。

Edited to fix when needing to interact with items behind GestureRecognizer.

编辑需要与 GestureRecognizer 后面的项目交互时进行修复。

Edit: Thanks @Rao for pointing this out. Added tap.cancelsTouchesInView = false.

编辑:感谢@Rao 指出这一点。添加tap.cancelsTouchesInView = false.

This should help you with having multiple UITextViewor UITextField

这应该有助于您拥有多个UITextViewUITextField

Create an extension of the view controller. This has worked much smoother for me and with less hassle than trying to use .resignFirstResponder()

创建视图控制器的扩展。这对我来说更顺畅,而且比尝试使用更省事.resignFirstResponder()

extension UIViewController
{
    func setupToHideKeyboardOnTapOnView()
    {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(
            target: self,
            action: #selector(UIViewController.dismissKeyboard))

        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

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

Call self.setupToHideKeyboardOnTapOnView()in the viewDidLoad

self.setupToHideKeyboardOnTapOnView()在 viewDidLoad 中调用

回答by iAnurag

Try this, it's tested and working:

试试这个,它已经过测试并且可以正常工作:

For Swift 3.0 / 4.0

对于 Swift 3.0 / 4.0

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

For Older Swift

对于较老的斯威夫特

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

回答by Giang

swift 3

迅捷 3

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}

回答by pixyzehn

In this case, there is UITapGesture as one of the choices. I tried to create sample code just in case. Like this,

在这种情况下,有 UITapGesture 作为选择之一。我试图创建示例代码以防万一。像这样,

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let tapGesture = UITapGestureRecognizer(target: self, action: "tap:")
        view.addGestureRecognizer(tapGesture)
    }

    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
}

回答by Devbot10

Working Solution for Swift 3 that works with ScrollView

适用于 ScrollView 的 Swift 3 工作解决方案

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // The next line is the crucial part
        // The action is where Swift 3 varies from previous versions
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tap(gesture:)))
        self.view.addGestureRecognizer(tapGesture)
    }

    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
}

Another questionthat talks about this issue that I referenced and used. The accepted answer no longer works in Swift 3. The current selected answer should be the below answer.

另一个问题是关于这个问题的会谈,我引用和使用。接受的答案不再适用于 Swift 3。当前选择的答案应该是以下答案。

回答by Vasily Bodnarchuk

Details

细节

  • Xcode 10.2.1 (10E1001), Swift 5
  • Xcode 10.2.1 (10E1001),Swift 5

Solution 1

解决方案1

endEditing(_:)

结束编辑(_:)

let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:)))
tableView.addGestureRecognizer(gesture)

Usage of solution 1. Full sample

溶液使用方法 1. 全样

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 30))
        textField.borderStyle = .roundedRect
        textField.placeholder = "Enter text"
        textField.becomeFirstResponder()
        view.addSubview(textField)
        let gesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:)))
        view.addGestureRecognizer(gesture)
    }
}

Solution 2

解决方案2

class TapGestureRecognizer

类 TapGestureRecognizer

import UIKit

class TapGestureRecognizer: UITapGestureRecognizer {

    let identifier: String

    init(target: Any?, action: Selector?, identifier: String) {
        self.identifier = identifier
        super.init(target: target, action: action)
    }

    static func == (left: TapGestureRecognizer, right: TapGestureRecognizer) -> Bool {
        return left.identifier == right.identifier
    }
}

extension UIView

扩展 UIView

import UIKit

extension UIView {

    private var hideKeybordOnTapIdentifier: String { return "hideKeybordOnTapIdentifier" }

    private var hideKeybordOnTapGestureRecognizer: TapGestureRecognizer? {
        let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard),
                                                       identifier: hideKeybordOnTapIdentifier)
        if let gestureRecognizers = self.gestureRecognizers {
            for gestureRecognizer in gestureRecognizers {
                if let tapGestureRecognizer = gestureRecognizer as? TapGestureRecognizer,
                    tapGestureRecognizer == hideKeyboardGesture {
                    return tapGestureRecognizer
                }
            }
        }
        return nil
    }

    @objc private func hideKeyboard() { endEditing(true) }

    var hideKeyboardOnTap: Bool {
        set {
            let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(hideKeyboard),
                                                           identifier: hideKeybordOnTapIdentifier)
            if let hideKeybordOnTapGestureRecognizer = hideKeybordOnTapGestureRecognizer {
                removeGestureRecognizer(hideKeybordOnTapGestureRecognizer)
                if gestureRecognizers?.count == 0 { gestureRecognizers = nil }
            }
            if newValue { addGestureRecognizer(hideKeyboardGesture) }
        }
        get { return hideKeybordOnTapGestureRecognizer == nil ? false : true }
    }
}

Usage of solution 2

解决方案2的使用

view.hideKeyboardOnTap = true

Solution 2 full Sample

解决方案 2 完整示例

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 30))
        textField.borderStyle = .roundedRect
        textField.placeholder = "Enter text"
        textField.becomeFirstResponder()
        view.addSubview(textField)
        view.hideKeyboardOnTap = true
    }
}

回答by handiansom

Check this out.

看一下这个。

override func viewDidLoad() {
    var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
    self.view.userInteractionEnabled = true
    self.view.addGestureRecognizer(tapGesture)
}

Then your tap handler is.

那么你的水龙头处理程序是。

  func handleTap(sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}

回答by Davina Arnold

For Swift 3

对于 Swift 3

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

回答by Venkat Ram

This works when touched outside input area for any number of input items.

当在输入区域外触摸任意数量的输入项目时,这会起作用。

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

回答by Lynkz7

I had the same problem and i finally solved it !

我有同样的问题,我终于解决了!

Set a TapGestureRecognizer in your Storyboard and then an Outlet in your ViewController

在 Storyboard 中设置 TapGestureRecognizer,然后在 ViewController 中设置一个 Outlet

@IBOutlet var tapGesture: UITapGestureRecognizer!

Then set an IBAction in your ViewController

然后在您的 ViewController 中设置一个 IBAction

@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
 self.view.endEditing(true)
} 

add these lines to your viewDidLoad method

将这些行添加到您的 viewDidLoad 方法中

override func viewDidLoad()
{
    super.viewDidLoad()
    self.view.addGestureRecognizer(tapGesture)
}

and its should work

它应该工作

Hope that will help !

希望会有所帮助!