如何从主视图滚动视图内的子视图中关闭 IOS Swift 中的键盘?
How to dismiss keyboard in IOS Swift from a subview inside a scroll view in the main view?
我在主视图的滚动视图中有 2 个子视图。基于滚动视图中的两个按钮,2sub 视图将显示和隐藏。两个子视图各有一个文本字段来输入数字。键盘是数字键盘。我已经为两个子视图实现了 func touchesBegan
和 UITapGestureRecognizer
,并添加了 resignFirstResponder()
和 endEditing(true)
。但我的键盘仍然没有消失。我无法在任何论坛中为此类情况找到合适的解决方案。
我正在使用 Swift 2.0 xcode7.1.1
编辑:我的代码(因为这是一个商业项目,所以我不能分享全部内容抱歉)
在这段代码中,当我在 viewAutomatic
中触摸外部时,键盘会启动。但是当我在 viewManual
中触摸外部时,键盘不会关闭。这对我来说太奇怪了。
@IBOutlet weak var viewScroll: UIScrollView!
@IBOutlet weak var txtNewBid: UITextField!
@IBOutlet weak var txtMyMaxBid: UITextField!
@IBOutlet weak var viewManual: UIView!
@IBOutlet weak var viewAutomatic: UIView!
override func viewDidLoad() {
let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: "singleTapped:")
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.numberOfTouchesRequired = 1
singleTapGestureRecognizer.enabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
self.viewManual.addGestureRecognizer(singleTapGestureRecognizer)
self.viewAutomatic.addGestureRecognizer(singleTapGestureRecognizer)
}
override func viewWillAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
func singleTapped(sender: UITapGestureRecognizer) {
self.view.endEditing(true)
self.viewManual.endEditing(true)
self.viewAutomatic.endEditing(true)
self.viewScroll.endEditing(true)
txtNewBid.resignFirstResponder()
txtMyMaxBid.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
txtNewBid.resignFirstResponder()
txtMyMaxBid.resignFirstResponder()
}
func keyboardWillShow(notification: NSNotification) {
// adjusting the scroll view for the keyboard
let frame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
if( self.viewManual.hidden == true)
{
self.viewScroll.frame.size.height -= frame.height
}
else
{
self.viewScroll.frame.size.height -= frame.height
}
let bottomOffset: CGPoint = CGPointMake(0, self.txtNewBid.frame.origin.y + self.txtNewBid.frame.size.height)
self.viewScroll.contentOffset = bottomOffset
}
func keyboardWillHide(notification: NSNotification) {
let frame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
if( self.viewManual.hidden == true)
{
self.viewScroll.frame.size.height += frame.height
}
else
{
self.viewScroll.frame.size.height += frame.height
}
}
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
txtNewBid.text = ""
txtMyMaxBid.text = ""
}
我猜你解决问题的方式不对。我假设控制器应该负责关闭键盘,但您可以尝试这样的事情(最好在您的托管视图控制器上):
yourView.endEditing(true) // boolean parameter specifies whether to force dismissal or not
endEditing(force)
应该遍历视图层次结构并检查是否有任何活动的响应者,所以这实际上应该有效。您是否检查过您是否确实引用了正确的视图?你能添加一些你的代码吗(请只添加必要的部分)?
我指出在托管控制器的视图上调用它很重要的原因是它会遍历所有子视图并检查是否有任何活动的响应者。
如果您有对文本字段的引用并且您确定它是哪一个,您也可以调用
yourTextField.resignFirstResponder()
我想这就是 endEditing(force)
内部所做的,它遍历所有子视图并在它遇到的任何文本字段上调用 resignFirstResponder()
,这也是第一响应者。
编辑
由于 UIScrollView
会拦截手势,我会直接将点击手势识别器添加到滚动视图中,如下所示:
self.viewScroll.addGestureRecognizer(singleTapGestureRecognizer)
然后做这样的事情:
func singleTapped(sender: UITapGestureRecognizer) {
// this should suffice
self.viewScroll.endEditing(true)
// or call it on the touched view (in this case the viewScroll)
// sender.view.endEditing(true)
}
我在主视图的滚动视图中有 2 个子视图。基于滚动视图中的两个按钮,2sub 视图将显示和隐藏。两个子视图各有一个文本字段来输入数字。键盘是数字键盘。我已经为两个子视图实现了 func touchesBegan
和 UITapGestureRecognizer
,并添加了 resignFirstResponder()
和 endEditing(true)
。但我的键盘仍然没有消失。我无法在任何论坛中为此类情况找到合适的解决方案。
我正在使用 Swift 2.0 xcode7.1.1
编辑:我的代码(因为这是一个商业项目,所以我不能分享全部内容抱歉)
在这段代码中,当我在 viewAutomatic
中触摸外部时,键盘会启动。但是当我在 viewManual
中触摸外部时,键盘不会关闭。这对我来说太奇怪了。
@IBOutlet weak var viewScroll: UIScrollView!
@IBOutlet weak var txtNewBid: UITextField!
@IBOutlet weak var txtMyMaxBid: UITextField!
@IBOutlet weak var viewManual: UIView!
@IBOutlet weak var viewAutomatic: UIView!
override func viewDidLoad() {
let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: "singleTapped:")
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.numberOfTouchesRequired = 1
singleTapGestureRecognizer.enabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
self.viewManual.addGestureRecognizer(singleTapGestureRecognizer)
self.viewAutomatic.addGestureRecognizer(singleTapGestureRecognizer)
}
override func viewWillAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
func singleTapped(sender: UITapGestureRecognizer) {
self.view.endEditing(true)
self.viewManual.endEditing(true)
self.viewAutomatic.endEditing(true)
self.viewScroll.endEditing(true)
txtNewBid.resignFirstResponder()
txtMyMaxBid.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
txtNewBid.resignFirstResponder()
txtMyMaxBid.resignFirstResponder()
}
func keyboardWillShow(notification: NSNotification) {
// adjusting the scroll view for the keyboard
let frame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
if( self.viewManual.hidden == true)
{
self.viewScroll.frame.size.height -= frame.height
}
else
{
self.viewScroll.frame.size.height -= frame.height
}
let bottomOffset: CGPoint = CGPointMake(0, self.txtNewBid.frame.origin.y + self.txtNewBid.frame.size.height)
self.viewScroll.contentOffset = bottomOffset
}
func keyboardWillHide(notification: NSNotification) {
let frame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
if( self.viewManual.hidden == true)
{
self.viewScroll.frame.size.height += frame.height
}
else
{
self.viewScroll.frame.size.height += frame.height
}
}
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
txtNewBid.text = ""
txtMyMaxBid.text = ""
}
我猜你解决问题的方式不对。我假设控制器应该负责关闭键盘,但您可以尝试这样的事情(最好在您的托管视图控制器上):
yourView.endEditing(true) // boolean parameter specifies whether to force dismissal or not
endEditing(force)
应该遍历视图层次结构并检查是否有任何活动的响应者,所以这实际上应该有效。您是否检查过您是否确实引用了正确的视图?你能添加一些你的代码吗(请只添加必要的部分)?
我指出在托管控制器的视图上调用它很重要的原因是它会遍历所有子视图并检查是否有任何活动的响应者。
如果您有对文本字段的引用并且您确定它是哪一个,您也可以调用
yourTextField.resignFirstResponder()
我想这就是 endEditing(force)
内部所做的,它遍历所有子视图并在它遇到的任何文本字段上调用 resignFirstResponder()
,这也是第一响应者。
编辑
由于 UIScrollView
会拦截手势,我会直接将点击手势识别器添加到滚动视图中,如下所示:
self.viewScroll.addGestureRecognizer(singleTapGestureRecognizer)
然后做这样的事情:
func singleTapped(sender: UITapGestureRecognizer) {
// this should suffice
self.viewScroll.endEditing(true)
// or call it on the touched view (in this case the viewScroll)
// sender.view.endEditing(true)
}