如何在触摸 UITextField 之外的任何地方时关闭键盘(swift)?
How to dismiss keyboard when touching anywhere outside UITextField (in swift)?
我正在处理一个有 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)
}
当我点击滚动视图外部时,它对我有用,但是当我点击滚动视图时,没有任何反应,键盘也没有隐藏。
在文本字段外点击 任何地方 时,有什么方法可以关闭键盘吗?
谢谢
在这种情况下,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()
}
}
我在 Obj-C 中创建了这个方法,无论用户当前在哪里打字,它都会隐藏键盘:
//call this method
+ (void)hideKeyboard {
//grab the main window of the application
UIWindow *window = [UIApplication sharedApplication].keyWindow;
//call our recursive method below
[self resignResponderForView:window];
}
//our recursive method
+ (void)resignResponderForView:(UIView *)view {
//resign responder from this view
//If it has the keyboard, then it will hide the keyboard
[view resignFirstResponder];
//if it has no subviews, then return back up the stack
if (view.subviews.count == 0)
return;
//go through all of its subviews
for (UIView *subview in view.subviews) {
//recursively call the method on those subviews
[self resignResponderForView:subview];
}
}
我希望这可以翻译成 Swift 并且有意义。它可以在应用程序的任何位置调用,并且无论 VC 你在做什么,它都会隐藏键盘。
转到键盘类型和Select默认值或您需要文本字段的任何内容。然后重写一个方法,随心所欲地调用它,我通常称它为 touchingBegins。以下是您忘记添加的内容
super.touchingBegins(touches, withEvent: event)
}
试试这个,它已经过测试并且可以工作:
对于Swift 3.0 / 4.0
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
年长者Swift
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
我遇到了同样的问题,我终于解决了!
在 Storyboard 中设置 TapGestureRecognizer,然后在 ViewController
中设置 Outlet
@IBOutlet var tapGesture: UITapGestureRecognizer!
然后在您的 ViewController
中设置一个 IBAction
@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
self.view.endEditing(true)
}
将这些行添加到您的 viewDidLoad 方法中
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addGestureRecognizer(tapGesture)
}
它应该有效
希望对您有所帮助!
已编辑 Swift 4
编辑:添加 @objc
。虽然这不是性能的最佳选择,但在有更好的解决方案之前,这里的一个实例应该不会引起太多问题。
编辑以修复需要与 GestureRecognizer 后面的项目交互时的问题。
编辑:感谢@Rao 指出这一点。添加了 tap.cancelsTouchesInView = false
.
这应该可以帮助您拥有多个 UITextView
或 UITextField
创建视图控制器的扩展。这对我来说工作起来更顺畅,而且比尝试使用 .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)
}
}
在viewDidLoad
中调用self.setupToHideKeyboardOnTapOnView()
每次触摸不同的 文本字段 关闭键盘或使用 resignfirstresponder
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(![touch.view isMemberOfClass:[UITextField class]]) {
[touch.view endEditing:YES];
}
}
当在输入区域外部触摸任意数量的输入项时,此方法有效。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
引入轻击手势识别器并为其设置和操作。
使用代码:
你的文本字段名称.resignfirsterresponder()
适用于 Swift 3 的工作解决方案与 ScrollView
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()
}
}
另一个 question 谈到了我引用和使用的这个问题。接受的答案不再适用于Swift 3. 当前选择的答案应该是下面的答案。
详情
- Xcode 10.2.1 (10E1001), Swift 5
解决方案 1
let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:)))
tableView.addGestureRecognizer(gesture)
解决方案 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)
}
}
解决方案 2
class 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
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 }
}
}
解决方案 2 的用法
view.hideKeyboardOnTap = true
解决方案 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
}
}
看看这个。
override func viewDidLoad() {
var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
self.view.userInteractionEnabled = true
self.view.addGestureRecognizer(tapGesture)
}
那么你的点击处理程序就是。
func handleTap(sender: UITapGestureRecognizer) {
self.view.endEditing(true)
}
swift 3
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
func findAndResignFirstResponder(_ stView: UIView) -> Bool {
if stView.isFirstResponder {
stView.resignFirstResponder()
return true
}
for subView: UIView in stView.subviews {
if findAndResignFirstResponder(subView) {
return true
}
}
return false
}
对于Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
//在 swift 4..它对我有用。
func setupKeyboardDismissRecognizer(){
let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(searchingActivity.dismissKeyboard))
self.view.addGestureRecognizer(tapRecognizer)
}
@objc func dismissKeyboard()
{
view.endEditing(true)
searchTableView.isHidden = true
}
//在viewDidLoad
中调用这个函数setupKeyboardDismissRecognizer()
在 Swift4 中
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
在Swift 4 或 5 你可以用 like..
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Key borad dismiss
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
//Key board hide on outside the textfield
@objc func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
}
我在Swift4中使用了下面的代码,你可以试试这个,
override func viewDidLoad() {
super.viewDidLoad()
// dismiss keyboard when tap outside a text field
let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourViewControllerName.dismissKeyboard))
view.addGestureRecognizer(tapGestureRecognizer)
}
//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)
}
我正在处理一个有 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)
}
当我点击滚动视图外部时,它对我有用,但是当我点击滚动视图时,没有任何反应,键盘也没有隐藏。
在文本字段外点击 任何地方 时,有什么方法可以关闭键盘吗? 谢谢
在这种情况下,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()
}
}
我在 Obj-C 中创建了这个方法,无论用户当前在哪里打字,它都会隐藏键盘:
//call this method
+ (void)hideKeyboard {
//grab the main window of the application
UIWindow *window = [UIApplication sharedApplication].keyWindow;
//call our recursive method below
[self resignResponderForView:window];
}
//our recursive method
+ (void)resignResponderForView:(UIView *)view {
//resign responder from this view
//If it has the keyboard, then it will hide the keyboard
[view resignFirstResponder];
//if it has no subviews, then return back up the stack
if (view.subviews.count == 0)
return;
//go through all of its subviews
for (UIView *subview in view.subviews) {
//recursively call the method on those subviews
[self resignResponderForView:subview];
}
}
我希望这可以翻译成 Swift 并且有意义。它可以在应用程序的任何位置调用,并且无论 VC 你在做什么,它都会隐藏键盘。
转到键盘类型和Select默认值或您需要文本字段的任何内容。然后重写一个方法,随心所欲地调用它,我通常称它为 touchingBegins。以下是您忘记添加的内容
super.touchingBegins(touches, withEvent: event)
}
试试这个,它已经过测试并且可以工作:
对于Swift 3.0 / 4.0
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
年长者Swift
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
我遇到了同样的问题,我终于解决了!
在 Storyboard 中设置 TapGestureRecognizer,然后在 ViewController
中设置 Outlet@IBOutlet var tapGesture: UITapGestureRecognizer!
然后在您的 ViewController
中设置一个 IBAction@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
self.view.endEditing(true)
}
将这些行添加到您的 viewDidLoad 方法中
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addGestureRecognizer(tapGesture)
}
它应该有效
希望对您有所帮助!
已编辑 Swift 4
编辑:添加 @objc
。虽然这不是性能的最佳选择,但在有更好的解决方案之前,这里的一个实例应该不会引起太多问题。
编辑以修复需要与 GestureRecognizer 后面的项目交互时的问题。
编辑:感谢@Rao 指出这一点。添加了 tap.cancelsTouchesInView = false
.
这应该可以帮助您拥有多个 UITextView
或 UITextField
创建视图控制器的扩展。这对我来说工作起来更顺畅,而且比尝试使用 .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)
}
}
在viewDidLoad
中调用self.setupToHideKeyboardOnTapOnView()
每次触摸不同的 文本字段 关闭键盘或使用 resignfirstresponder
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(![touch.view isMemberOfClass:[UITextField class]]) {
[touch.view endEditing:YES];
}
}
当在输入区域外部触摸任意数量的输入项时,此方法有效。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
引入轻击手势识别器并为其设置和操作。
使用代码:
你的文本字段名称.resignfirsterresponder()
适用于 Swift 3 的工作解决方案与 ScrollView
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()
}
}
另一个 question 谈到了我引用和使用的这个问题。接受的答案不再适用于Swift 3. 当前选择的答案应该是下面的答案。
详情
- Xcode 10.2.1 (10E1001), Swift 5
解决方案 1
let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:)))
tableView.addGestureRecognizer(gesture)
解决方案 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)
}
}
解决方案 2
class 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
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 }
}
}
解决方案 2 的用法
view.hideKeyboardOnTap = true
解决方案 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
}
}
看看这个。
override func viewDidLoad() {
var tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap))
self.view.userInteractionEnabled = true
self.view.addGestureRecognizer(tapGesture)
}
那么你的点击处理程序就是。
func handleTap(sender: UITapGestureRecognizer) {
self.view.endEditing(true)
}
swift 3
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
func findAndResignFirstResponder(_ stView: UIView) -> Bool {
if stView.isFirstResponder {
stView.resignFirstResponder()
return true
}
for subView: UIView in stView.subviews {
if findAndResignFirstResponder(subView) {
return true
}
}
return false
}
对于Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
//在 swift 4..它对我有用。
func setupKeyboardDismissRecognizer(){
let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(searchingActivity.dismissKeyboard))
self.view.addGestureRecognizer(tapRecognizer)
}
@objc func dismissKeyboard()
{
view.endEditing(true)
searchTableView.isHidden = true
}
//在viewDidLoad
中调用这个函数setupKeyboardDismissRecognizer()在 Swift4 中
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
在Swift 4 或 5 你可以用 like..
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Key borad dismiss
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
//Key board hide on outside the textfield
@objc func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
}
我在Swift4中使用了下面的代码,你可以试试这个,
override func viewDidLoad() {
super.viewDidLoad()
// dismiss keyboard when tap outside a text field
let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourViewControllerName.dismissKeyboard))
view.addGestureRecognizer(tapGestureRecognizer)
}
//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)
}