How to dismiss keyboard when touching anywhere out

2019-01-16 06:14发布

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:

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 anywhere outside the textfield? thanks

15条回答
时光不老,我们不散
2楼-- · 2019-01-16 06:54

Edited for 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.

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

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

This should help you with having multiple UITextView or UITextField

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

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

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

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

Call self.hideKeyboard() in the viewDidLoad

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-01-16 06:54

Introduce a tap gesture recogniser and set and action for it.

Use the code:

nameofyourtextfield.resignfirstresponder()

查看更多
闹够了就滚
4楼-- · 2019-01-16 06:55

swift 3

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
查看更多
Melony?
5楼-- · 2019-01-16 06:57

Go to Keyboard Type and Select Default or whatever you need the TextField for. Then override a method call it whatever you want i usually call it touchingBegins. Below is what you forgot to add

super.touchingBegins(touches, withEvent: event)
 }
查看更多
该账号已被封号
6楼-- · 2019-01-16 07:02

Details

xCode 8.2.1, Swift 3

Task

Set UITapGestureRecognizer for view of UIViewController which will close keyboard and make this functionality as Bool property of UIView.

Complex implementation but the usage is in one line

class TapGestureRecognizer

import UIKit

class TapGestureRecognizer: UITapGestureRecognizer {

    let identifier: String

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

    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 disableKeybordWhenTappedGestureRecognizerIdentifier:String {
        return "disableKeybordWhenTapped"
    }

    private var disableKeybordWhenTappedGestureRecognizer: TapGestureRecognizer? {

        let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: disableKeybordWhenTappedGestureRecognizerIdentifier)

        if let gestureRecognizers = self.gestureRecognizers {
            for gestureRecognizer in gestureRecognizers {
                if let tapGestureRecognizer = gestureRecognizer as? TapGestureRecognizer, tapGestureRecognizer == hideKeyboardGesture, tapGestureRecognizer == hideKeyboardGesture {
                    return tapGestureRecognizer
                }
            }
        }
        return nil
    }

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

    var disableKeybordWhenTapped: Bool {

        set {
            let hideKeyboardGesture = TapGestureRecognizer(target: self, action: #selector(UIView.hideKeyboard), identifier: disableKeybordWhenTappedGestureRecognizerIdentifier)

            if let disableKeybordWhenTappedGestureRecognizer = self.disableKeybordWhenTappedGestureRecognizer {
                removeGestureRecognizer(disableKeybordWhenTappedGestureRecognizer)
                if gestureRecognizers?.count == 0 {
                    gestureRecognizers = nil
                }
            }

            if newValue {
                addGestureRecognizer(hideKeyboardGesture)
            }
        }

        get {
            return disableKeybordWhenTappedGestureRecognizer == nil ? false : true
        }
    }
}

Usage

view.disableKeybordWhenTapped = true

Full Sample

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"
        view.addSubview(textField)

        view.disableKeybordWhenTapped = true
    }
}
查看更多
小情绪 Triste *
7楼-- · 2019-01-16 07:02

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)
    }
查看更多
登录 后发表回答