¿Cómo ocultar el teclado rápidamente al presionar la tecla de retorno?

214

Estoy usando UITextfiedmientras hago clic en el teclado textfied aparece pero cuando presioné la returntecla, el teclado no está desapareciendo. Use el siguiente código:

func textFieldShouldReturn(textField: UITextField!) -> Bool // called when 'return' key pressed. return NO to ignore.
{
    return true;
}

El método resignfirstresponder no está funcionando.

Ashwinkumar Mangrulkar
fuente
10
¿Has considerado aceptar la respuesta de RSC? aceptar respuestas es lo que hace que este lugar funcione y se considera una buena práctica.
Juan Boero
77
Si alguna respuesta cumple con su requisito, márquela como respuesta para que otras personas puedan obtener ayuda.
Syed Md. Kamruzzaman

Respuestas:

397

Puede hacer que la aplicación descarte el teclado usando la siguiente función

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true)
    return false
}

Aquí hay un ejemplo completo para ilustrar mejor eso:

//
//  ViewController.swift
//
//

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet var myTextField : UITextField

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.myTextField.delegate = self
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        return false
    }
}

Fuente del código: http://www.snip2code.com/Snippet/85930/swift-delegate-sample

rsc
fuente
22
Me faltaba "self.myTextField.delegate = self;" ¡Gracias!
tylerlindell
44
Me faltaba el UITextFieldDelegate!
Cesare
1
@kommradHomer, sin duda hay algo más que hace que tu teclado no se muestre. Si lo desea, coloque su código en pastebin y pegue el enlace aquí para que lo vea.
rsc
1
@RSC probablemente tenías razón. yo soy un novato 2 días en iOS, por lo que de alguna manera se deshicieron de mi problema y todo funcionaba como usted sugiere :)
kommradHomer
1
Así que trabaja para mí (swift 3): func textFieldShouldReturn(textField: UITextField) -> Bool {cambia a func textFieldShouldReturn(_ textField: UITextField) -> Bool {
sea-kg
112

La return trueparte de esto solo le dice al campo de texto si está permitido regresar o no.
Debe decirle manualmente al campo de texto que descarte el teclado (o cualquiera que sea su primer respondedor), y esto se hace de la siguiente resignFirstResponder()manera:

// Called on 'Return' pressed. Return false to ignore.

func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
    textField.resignFirstResponder()
    return true
}
Mick MacCallum
fuente
2
gracias ... en mi caso, el método "resignFirstResponder ()" no se estaba obteniendo automáticamente y pensé que no era compatible, pero mientras escribía manualmente funcionaba bien ... gracias, eso es lo que estoy buscando.
Ashwinkumar Mangrulkar
@AshwinMangrulkar puede esperar que en la versión beta de Xcode 6 la función de finalización automática pueda verse perjudicada.
Paul Brewczynski
1
y, por supuesto, el punto y coma después de "verdadero" ya no es necesario
36 By Design
1
¿No es un requisito que su viewController cumple UITextFieldDelegate?
Miel
1
en lugar de self.view.endEditing () esta respuesta es apropiada y el enfoque correcto
saigen
45
  • Agregar UITextFieldDelegatea la declaración de clase:

    class ViewController: UIViewController, UITextFieldDelegate
  • Conéctelo textfieldo escríbalo mediante programación

    @IBOutlet weak var userText: UITextField!
  • configure su controlador de vista ya que los campos de texto delegados en la vista se cargaron:

    override func viewDidLoad() {
    super.viewDidLoad()
    self.userText.delegate = self
    }
  • Agregue la siguiente función

    func textFieldShouldReturn(userText: UITextField!) -> Bool {
        userText.resignFirstResponder()
        return true;
    }

    Con todo esto, su teclado comenzará a descartarse tocando fuera del campo de texto y presionando la tecla de retorno.

Codetard
fuente
¡Gracias hombre! Me faltaba esto: UITextFieldDelegate... muchas gracias!
Adriano Tadao
Por alguna razón, cuando configuro txtField.delegate = self, no puedo escribir dentro de ese campo de texto una vez que ejecuto la aplicación
Jesus Rodriguez
@JesusAdolfoRodriguez debe haber una razón detrás de ese error, aunque este código no causa ningún problema. : D ¡Feliz codificación!
Codetard
Gracias por el paso a paso. Esto fue más útil para mí que solo un bloque de código.
kenhkelly
1
"con todo esto, su teclado comenzará a descartarse tocando fuera del campo de texto" - No es cierto. textFieldShouldReturn se llama solo al presionar el botón de retorno.
Jurásico
39

Swift 4.2 - No se necesita delegado

Puede crear una salida de acción desde UITextField para la " Acción principal activada " y renunciar al primer respondedor en el parámetro del remitente que se pasa:

Crear salida de acción

@IBAction func done(_ sender: UITextField) {
    sender.resignFirstResponder()
}

Súper simple

(Gracias al video de 60 segundos de Scott Smith por informarme sobre esto: https://youtu.be/v6GrnVQy7iA )

Mark Moeykens
fuente
si tenemos múltiples campos de texto en una página, entonces debemos hacerlo para cada campo de texto ...
DragonFire
@DragonFire Puede asignar múltiples campos de texto a la misma salida. Simplemente arrastre desde la salida Activada por acción primaria en el inspector de salida (lado izquierdo de la pantalla) hasta la IBAction en su código
Brad Root
Es bueno tener en cuenta que arrastrar directamente desde el campo de texto en el guión gráfico predeterminará la acción vinculada a Edición Finalizada, en lugar de Acción primaria activada, por lo que debe hacerse desde el Inspector de conexiones de la barra lateral.
Nube
Asombroso. No sabía eso. Gracias.
Numan Karaaslan
También funciona con Swift 2, si a alguien todavía le importa. Gracias.
siralexsir88
22

Solución simple de Swift 3: agregue esta función a sus controladores de vista que cuentan con un campo de texto:

@IBAction func textField(_ sender: AnyObject) {
    self.view.endEditing(true);
}

Luego abra su editor asistente y asegúrese de que su Main.storyboard esté en un lado de su vista y que el archivo de controlador de vista deseado.swift esté en el otro. Haga clic en un campo de texto y luego seleccione en la pestaña 'Mostrar el Inspector de conexiones' del panel de utilidades del lado derecho. Controle el arrastre desde 'Terminó al salir' a la función anterior en su archivo rápido. Repita para cualquier otro campo de texto en esa escena y enlace a la misma función.

elarcoiris
fuente
14

@RSC

para mí, la adición crítica en Xcode Versión 6.2 (6C86e) está en override func viewDidLoad()

 self.input.delegate = self;

Intenté que funcionara con la tecla de retorno durante horas hasta que encontré tu publicación, RSC. ¡Gracias!

Además, si desea ocultar el teclado si toca en cualquier otro lugar de la pantalla:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.view.endEditing(true);
    }
Tobias F. Meier
fuente
12

Para obtener el descarte automático del teclado, pongo este código dentro de uno de los métodos de la clase de mi campo de texto personalizado:

textField.addTarget(nil, action:"firstResponderAction:", forControlEvents:.EditingDidEndOnExit)

Sustituya el nombre de su outlet por textField.

tipo de paz
fuente
1
Excepcional. Esta es la mejor y más corta opción en mi opinión. Especialmente cuando estás creando un campo de texto dentro de otro método. Como dentro de un encabezado de vista de tabla.
kakubei
Lo sentimos, ¿dónde exactamente tienes que poner esto y qué tienes que hacer para cerrar el teclado? Puse mytextfield.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)(versión Swift 5) viewDidLoadpero no funcionó ni regresar ni tocar en algún lugar fuera del campo de texto. Obtuve los campos de texto creando una salida cada uno.
Neph
Lo puse en una subclase de una clase personalizada que hereda de UIViewController. La subclase también se ajusta a UITextViewDelegate y UITextFieldDelegate. Lo puse en el viewDidAppearmétodo de esa clase. UIAlertController.addTextField(configurationHandler: {(textField: UITextField!) in textField.delegate = self textField.addTarget(self, action: #selector(MySubclass.textChanged(_:)), for: .editingChanged) })Esto podría ser demasiado específico para mi caso, pero espero que ayude. Intente hacer la llamada dentro viewDidAppeary conforme a los delegados si es necesario.
paz
10

Otra forma de hacerlo que utiliza principalmente el guión gráfico y le permite fácilmente tener múltiples campos de texto es:

@IBAction func resignKeyboard(sender: AnyObject) {
    sender.resignFirstResponder()
}

Conecte todos sus campos de texto para ese controlador de vista a esa acción en el Did End On Exitevento de cada campo.

James Thompson
fuente
Perdón por el golpe, pero estoy probando este método en mi aplicación y no parece estar funcionando. Tengo un campo de texto en la barra de navegación y lo he conectado a esta acción con ese evento como dijiste, pero no funciona en tiempo de ejecución.
wasimsandhu
Esto se bloqueará si el remitente es de tipo UIBarButtonItem. Si agrego la barra de herramientas con el botón Listo al teclado numérico, entonces su código se bloqueará con el selector no reconocido enviado al registro de instancias.
Jayprakash Dubey
8

Yo sugeriría iniciar la clase desde RSC:

import Foundation
import UIKit

// Don't forget the delegate!
class ViewController: UIViewController, UITextFieldDelegate {

required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

@IBOutlet var myTextField : UITextField?

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.myTextField.delegate = self;
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func textFieldShouldReturn(textField: UITextField!) -> Bool {
    self.view.endEditing(true);
    return false;
}

}

ARTES LAOMUSICAS
fuente
8

Cuando el usuario toca el botón Listo en el teclado de texto, se generará un evento Did End On Exit; en ese momento, necesitamos decirle al campo de texto que ceda el control para que el teclado desaparezca. Para hacer eso, necesitamos agregar un método de acción a nuestra clase de controlador. Seleccione ViewController.swift y agregue el siguiente método de acción:

@IBAction func textFieldDoneEditing(sender: UITextField) {
sender.resignFirstResponder()}

Seleccione Main.storyboard en el Navegador de proyectos y abra el inspector de conexiones. Arrastre desde el círculo al lado de Did End On Exit al icono amarillo del Controlador de vista en el guión gráfico y suéltelo. Aparecerá un pequeño menú emergente que contiene el nombre de una sola acción, la que acabamos de agregar. Haga clic en la acción textFieldDoneEditing para seleccionarla y listo.

Ian Seth Colin
fuente
8

Aquí está la actualización de Swift 3.0 al comentario de peacetype:

textField.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
Darth Flyeater
fuente
esta es una respuesta limpia
po5i
Esta debería ser la respuesta aceptada. Trabajó en un solo intento.
Jaswant Singh
7

Odio agregar la misma función a cada UIViewController. Al extender UIViewController para admitir UITextFieldDelegate, puede proporcionar un comportamiento predeterminado de "retorno presionado".

extension UIViewController: UITextFieldDelegate{
    public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true;
    }
}

Cuando crea nuevos UIViewController y UITextField, todo lo que tiene que hacer es escribir un código de línea en su UIViewController.

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

Incluso puede omitir este código de línea conectando delegado en Main.storyboard. (Usando "ctrl" y arrastre de UITextField a UIViewController)

Wu Yuan Chun
fuente
5

Swift 3

Agregue este código a continuación a su VC

//hide keyboard when user tapps on return key on the keyboard
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true);
    return false;
}

Funciona para mi

Gilad Brunfman
fuente
3

Asegúrese de que su delegado textField esté configurado en el controlador de vista desde el que está escribiendo su código relacionado con el campo de texto.

self.textField.delegate = self
Miladinho
fuente
3

Rápido

Usando la función opcional de UITextFieldDelegate.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    return textField.endEditing(false)
}

falsesignifica que se le puede pedir a ese campo que renuncie. true- forzar la renuncia.

dimpiax
fuente
3
override func viewDidLoad() {
    super.viewDidLoad()

    let tap = UITapGestureRecognizer(target: self, action: #selector(handleScreenTap(sender:)))
    self.view.addGestureRecognizer(tap)}

entonces usas esta función

func handleScreenTap(sender: UITapGestureRecognizer) {
    self.view.endEditing(true)
}
Santi RibeiroO
fuente
2

puedes poner esto en cualquier lugar pero no en un UIButton

 func TextFieldEndEditing(text fiend name: UITextField!) -> Bool
{
    return (false)
}

entonces puedes poner este código en un botón (también, por ejemplo):

self.view.endEditing(true)

esto funcionó para mí

Blake Scott
fuente
2

En el controlador de vista que está utilizando:

//suppose you are using the textfield label as this

@IBOutlet weak var emailLabel: UITextField!
@IBOutlet weak var passwordLabel: UITextField!

//then your viewdidload should have the code like this
override func viewDidLoad() {
        super.viewDidLoad()

        self.emailLabel.delegate = self
        self.passwordLabel.delegate = self

    }

//then you should implement the func named textFieldShouldReturn
 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

// -- then, further if you want to close the keyboard when pressed somewhere else on the screen you can implement the following method too:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true);
    }
kanishk verma
fuente
Me gustan los toquesBegan func, funciona en swift 4 gracias.
AJ Hernández
-1

debe conectar el UITextfied con un delegado del controlador de vista para hacer que esta función se llame

Abdulrahman Masoud
fuente
-1

Todo en uno Ocultar teclado y mover vista al abrir teclado: Swift 5

override func viewDidLoad() {
    super.viewDidLoad()
    let tap = UITapGestureRecognizer(target: self, action: #selector(taped))
    view.addGestureRecognizer(tap)
    NotificationCenter.default.addObserver(self, selector: #selector(KeyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(KeyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}


   override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
 @objc func taped(){

    self.view.endEditing(true)

}

@objc func KeyboardWillShow(sender: NSNotification){

    let keyboardSize : CGSize = ((sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.size)!
    if self.view.frame.origin.y == 0{
        self.view.frame.origin.y -= keyboardSize.height
    }


}

@objc func KeyboardWillHide(sender : NSNotification){

    let keyboardSize : CGSize = ((sender.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size)!
    if self.view.frame.origin.y != 0{
        self.view.frame.origin.y += keyboardSize.height
    }

}
Imran Rasheed
fuente