触摸 UITextField 以外的任何地方时如何关闭键盘(快速)?
Posted
技术标签:
【中文标题】触摸 UITextField 以外的任何地方时如何关闭键盘(快速)?【英文标题】:How to dismiss keyboard when touching anywhere outside UITextField (in swift)? 【发布时间】:2015-11-23 17:47:08 【问题描述】:我正在开发一个具有 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)
当我在滚动视图之外点击时它对我有用,但是当我点击滚动视图时没有任何反应并且键盘不会隐藏。
在文本字段外点击anywhere时,有什么方法可以关闭键盘? 谢谢
【问题讨论】:
【参考方案1】:在这种情况下,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()
【讨论】:
感谢它的工作。但我还有另一个问题,我有一个带有 5 个文本字段的视图控制器。有没有一种很好的方法来做同样的事情,而不需要一个一个地为他们调用“resignFirstResponder”方法? 另一个问题,当我点击文本字段外的任何地方时,有什么办法可以关闭键盘吗?例如当我点击一个按钮时? @white-hat 你能把这个问题当作另一个问题来问吗? @WhiteHat 将您的 5 个文本字段放在一个出口集合中。然后创建一个对集合进行迭代并在每个文本字段上调用 resignFirstResponder 的 dismissKeyboard 方法。您可以从手势识别器和按钮操作中调用此方法。 @WhiteHat ViewController.View 可以调用 endEdting【参考方案2】:我在 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 或任何东西,它都会隐藏键盘。
【讨论】:
您可能想查看-[UIView endEditing:]
。【参考方案3】:
转到键盘类型并选择默认或任何您需要的文本字段。然后覆盖一个方法调用它任何你想要的,我通常称之为touchBegins。以下是您忘记添加的内容
super.touchingBegins(touches, withEvent: event)
【讨论】:
【参考方案4】:试试这个,它已经过测试并且可以工作:
适用于 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)
【讨论】:
点击 UIScrollView 时这对我不起作用 请注意,这已更改为在 Swift 2 中覆盖 func touchesBegan(touches: Settap.cancelsTouchesInView = false
。希望对您有所帮助。【参考方案5】:
我遇到了同样的问题,我终于解决了!
在 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)
它应该可以工作
希望这会有所帮助!
【讨论】:
【参考方案6】:为 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()
【讨论】:
工作精美且优雅。这应该是答案 我不得不在 Swift 4 中添加 @objc funcdismissKeyboard() @MCR 你是对的。我更新了答案以反映这一点,直到找到更明确的方法。 警告:如果您说,同一视图上的 tableView,此代码将阻止单元格点击,并且您的 didSelectRow 不会触发。为了避免这种情况,您需要在addGestureRecognizer
之前添加 tap.cancelsTouchesInView = false
有谁知道如何防止dismissKeyboard()
被调用,如果点击是在一个嵌入在self 中的UIViewContainer
的视图中完成的?【参考方案7】:
文本域每次触摸都不同,关闭键盘或使用resignfirstresponder
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
UITouch *touch = [touches anyObject];
if(![touch.view isMemberOfClass:[UITextField class]])
[touch.view endEditing:YES];
【讨论】:
【参考方案8】:当在输入区域外触摸任意数量的输入项时,此方法有效。
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
self.view.endEditing(true)
【讨论】:
【参考方案9】:引入点击手势识别器并为其设置和操作。
使用代码:
nameofyourtextfield.resignfirstresponder()
【讨论】:
【参考方案10】:适用于 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()
另一个question 谈到了我引用和使用的这个问题。接受的答案在 Swift 3 中不再有效。当前选择的答案应该是以下答案。
【讨论】:
@JoeBlow 我相信你错了。您应该辞去 textField 的第一响应者的职务。不是景色。我在我当前的项目中有这个代码,只是在一个新项目中测试了它。更不用说,我的答案只是 Pixyzehn 写的答案的更新版本。 嘿,开发者@Devbot10 - 不要犹豫,将其编辑回您之前的内容。你知道,我可能对.endEditing
感到困惑,它确实在下面的所有视图中递归。【参考方案11】:
详情
Xcode 10.2.1 (10E1001)、Swift 5解决方案 1
endEditing(_:)
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
类 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
扩展 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
【讨论】:
【参考方案12】:看看这个。
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)
【讨论】:
imgView.addGestureRecognizer(tapGesture)
应该是self.view.addGestureRecognizer(tapGesture)
是的,对不起,我没有注意到。我在输入什么。谢谢@AhsanEbrahim【参考方案13】:
斯威夫特 3
override func viewDidLoad()
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
【讨论】:
【参考方案14】: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
【讨论】:
【参考方案15】:对于 Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
self.view.endEditing(true)
【讨论】:
【参考方案16】://在 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()
【讨论】:
【参考方案17】:在 Swift4 中
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
self.view.endEditing(true)
【讨论】:
【参考方案18】:在 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)
【讨论】:
【参考方案19】:我在 Swift 4 中使用了以下代码,你可以试试这个,
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)
【讨论】:
以上是关于触摸 UITextField 以外的任何地方时如何关闭键盘(快速)?的主要内容,如果未能解决你的问题,请参考以下文章
当用户按下其他控件/空格时,如何取消对UITextField的聚焦?