触摸UITextField外的任何地方时如何解除键盘(在swift中)?

问题描述 投票:55回答:17

我正在开发一个具有UIViewController的项目,在视图控制器上,在scrollview上有一个UIScrollView和一个UITextField。像这样:我试图解除键盘并在文本字段中键入一些文本后隐藏它并点击文本域外的任何地方。我试过以下代码:

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

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

当我在滚动视图外面点击时它适用于我,但当我点击滚动视图时没有任何反应,键盘也不会隐藏。

点击文本域外的任何位置时有没有办法解除键盘?谢谢

ios swift uitextfield uikeyboard
17个回答
103
投票

编辑为Swift 4

编辑:添加@objc。虽然这不是性能的最佳选择,但这里的一个实例不应该导致太多问题,直到有更好的解决方案。

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

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

这应该可以帮助你有多个UITextViewUITextField

创建视图控制器的扩展。这对我来说更顺畅,并且比尝试使用.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()


1
投票

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

在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)
}

它应该工作

希望有所帮助!


1
投票

每次触摸不同的文本字段都会关闭键盘或使用resignfirstresponder

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 UITouch *touch = [touches anyObject];
 if(![touch.view isMemberOfClass:[UITextField class]]) {
     [touch.view endEditing:YES];
 }
}

1
投票
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
}

0
投票

我在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或任何东西,它都会隐藏键盘。


0
投票

转到“键盘类型”并选择“默认”或您需要TextField的任何内容。然后覆盖一个方法,无论你想要什么,我通常称之为touchBegins。以下是您忘记添加的内容

super.touchingBegins(touches, withEvent: event)
 }

0
投票

引入轻拍手势识别器并为其设置和操作。

使用代码:

nameofyourtextfield.resignfirstresponder()


0
投票

//在快速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()


0
投票

在Swift4中

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

56
投票

试试这个,经过测试和工作:

适用于Swift 3.0 / 4.0

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

对于老年人斯威夫特

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

16
投票

迅捷3

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

13
投票

在这种情况下,有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()
    }
}

11
投票

适用于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中不再有效。当前选择的答案应该是以下答案。


5
投票

看一下这个。

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

5
投票

细节

  • 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
    }
}

3
投票

对于Swift 3

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

2
投票

当在输入区域外触摸任意数量的输入项时,这都有效。

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.view.endEditing(true)
    }
© www.soinside.com 2019 - 2024. All rights reserved.