Как отклонить клавиатуру при касании в любом месте за пределами UITextField (в swift)?
Я работаю над проектом, который имеет UIViewController, на контроллере представления есть UIScrollView и UITextField на scrollview. вроде этого: Я пытаюсь отключить клавиатуру и скрыть ее после ввода текста в текстовое поле и нажмите в любом месте за пределами текстового поля. Я пробовал следующий код:
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self;
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
это работает для меня, когда я нажимаю вне scrollview, но когда я нажимаю на scrollview ничего не происходит, и клавиатура не прятаться.
есть ли способ закрыть клавиатуру при нажатии в любом месте за пределами текстового поля? спасибо
15 ответов
отредактировано для Swift 4
Edit: Добавлено @objc
. Хотя это не лучший вариант для производительности, один экземпляр здесь не должен вызывать слишком много проблем, пока не будет лучшего решения.
отредактировано для исправления при необходимости взаимодействия с элементами за GestureRecognizer.
Edit: спасибо @Rao за указание на это. Добавлено tap.cancelsTouchesInView = false
.
это должно помочь вам иметь несколько UITextView
или UITextField
создайте расширение контроллера вида. Это сработало намного плавнее для меня и с меньшими хлопотами, чем попытка использовать .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)
}
}
вызов self.hideKeyboard()
в viewDidLoad
попробуйте это, он протестирован и работает:
Для 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)
}
в этом случае одним из вариантов является 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()
}
}
рабочее решение для 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()
}
}
другое вопрос это говорит об этой проблеме, на которую я ссылался и использовал. Принято отвечать больше не работает в Swift 3. Текущий выбранный ответ должен быть ответом ниже.
swift 3
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
}
подробности
xCode 8.2.1, Swift 3
задание
установите UITapGestureRecognizer для просмотра UIViewController, который закроет клавиатуру и сделает эту функцию свойством Bool UIView.
сложная реализация, но использование находится в одной строке
класс 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
}
}
расширение 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
}
}
}
использование
view.disableKeybordWhenTapped = true
полный Образец
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
}
}
зацени.
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)
}
это работает при касании вне области ввода для любого количества входных элементов.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
Для Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
у меня была такая же проблема, и я наконец решил его !
установите TapGestureRecognizer в раскадровке, а затем розетку в ViewController
@IBOutlet var tapGesture: UITapGestureRecognizer!
затем установите IBAction в своем ViewController
@IBAction func DismissKeyboard(sender: UITapGestureRecognizer)
{
self.view.endEditing(true)
}
добавьте эти строки в метод viewDidLoad
override func viewDidLoad()
{
super.viewDidLoad()
self.view.addGestureRecognizer(tapGesture)
}
и
надеюсь, что поможет !
каждое касание отличается от текстовое поле закрыть клавиатуру или использовать resignfirstresponder
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(![touch.view isMemberOfClass:[UITextField class]]) {
[touch.view endEditing:YES];
}
}
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
}
Я создал этот метод в 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 вы находитесь на или что-нибудь.
перейдите к типу клавиатуры и выберите по умолчанию или все, что вам нужно текстовое поле для. Затем переопределите метод, назовите его как хотите, я обычно называю его touchingBegins. Ниже то, что вы забыли добавить
super.touchingBegins(touches, withEvent: event)
}
введите распознаватель жестов крана и установите и действие для него.
использовать код:
nameofyourtextfield.resignfirstresponder()