Como ocultar rapidamente o teclado ao pressionar a tecla Enter?

214

Estou usando UITextfiedenquanto clico no teclado textfied aparecer, mas quando pressionei a returntecla, o teclado não está desaparecendo. Eu usei o seguinte código:

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

o método resignfirstresponder não está entrando na função.

Ashwinkumar Mangrulkar
fonte
10
você considerou aceitar a resposta do RSC? aceitar respostas é o que faz esse local funcionar e é considerado uma boa prática.
Juan Boero
7
se alguma resposta atender aos seus requisitos, marque como resposta para que outras pessoas possam obter ajuda.
Syed Md. Kamruzzaman 8/03/16

Respostas:

397

Você pode fazer o aplicativo dispensar o teclado usando a seguinte função

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

Aqui está um exemplo completo para ilustrar melhor isso:

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

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

rsc
fonte
22
Estava faltando "self.myTextField.delegate = self;" Obrigado!
tylerlindell
4
Eu estava sentindo falta do UITextFieldDelegate!
Cesare
1
@kommradHomer, sem dúvida, há outra coisa que está fazendo o teclado não aparecer. Se você quiser, coloque seu código em pastebin e cole o link aqui para eu ver.
rsc
1
@RSC você provavelmente estava certo. eu sou um novato 2 dias no iOS, então de alguma forma se livrou do meu problema e tudo funcionou como você sugeriu :)
kommradHomer
1
Então trabalhe para mim (swift 3): func textFieldShouldReturn(textField: UITextField) -> Bool {mude para func textFieldShouldReturn(_ textField: UITextField) -> Bool {
sea-kg
112

A return trueparte disso informa apenas ao campo de texto se é permitido retornar ou não.
Você deve informar manualmente o campo de texto para descartar o teclado (ou o que quer que seja o primeiro a responder), e isso é feito da seguinte resignFirstResponder()maneira:

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

func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
    textField.resignFirstResponder()
    return true
}
Mick MacCallum
fonte
2
obrigado ... no meu caso "resignFirstResponder ()" método não estava recebendo automaticamente e eu pensei que não estava apoiando, mas enquanto escrevia manualmente o seu trabalho bem .. obrigado que estou procurando.
Ashwinkumar Mangrulkar
@AshwinMangrulkar, você pode esperar que na versão beta do Xcode 6 o recurso de preenchimento automático possa ser prejudicado.
Paul Brewczynski
1
e, é claro, o ponto-e-vírgula após "true" não é mais necessário
36
1
não é um requisito que o seu viewController esteja em conformidade UITextFieldDelegate?
Honey
1
em vez de self.view.endEditing () esta resposta é adequada e a abordagem correta
saigen
45
  • Adicione UITextFieldDelegateà declaração de classe:

    class ViewController: UIViewController, UITextFieldDelegate
  • Conecte textfieldou escreva programaticamente

    @IBOutlet weak var userText: UITextField!
  • defina seu controlador de exibição como os campos de texto delegados na exibição foram carregados:

    override func viewDidLoad() {
    super.viewDidLoad()
    self.userText.delegate = self
    }
  • Adicione a seguinte função

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

    com tudo isso, seu teclado começará a ser descartado tocando fora do campo de texto e pressionando a tecla Enter.

Codetard
fonte
Valeu cara! Eu estava sentindo falta disso: UITextFieldDelegate... muito obrigado!
Adriano Tadao
Por alguma razão, quando eu definir o txtField.delegate = auto, eu não posso digitar dentro desse campo de texto uma vez que eu executar o aplicativo
Jesus Rodriguez
@JesusAdolfoRodriguez, deve haver uma razão por trás desse erro, embora este código não cause nenhum problema. : D Feliz codificação!
Codetard
Obrigado pelo passo a passo. Isso foi mais útil para mim do que apenas um bloco de código.
precisa saber é o seguinte
1
"com tudo isso, seu teclado começará a ser descartado tocando fora do campo de texto" - Não é verdade. O textFieldShouldReturn é chamado apenas ao pressionar o botão de retorno.
Jurasic
38

Swift 4.2 - Não é necessário delegar

Você pode criar uma saída de ação do UITextField para a " Ação primária acionada " e renunciar a primeira resposta no parâmetro sender passado:

Criar tomada de ação

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

Super simples.

(Obrigado ao vídeo de 60 segundos de Scott Smith por me informar sobre isso: https://youtu.be/v6GrnVQy7iA )

Mark Moeykens
fonte
se tivermos vários campos de texto em uma página, será necessário fazê-lo para cada campo de texto ... #
187
@DragonFire Você pode atribuir vários campos de texto à mesma tomada. Arraste Apenas a partir da ação primária Provocado tomada no Inspetor de saída (lado esquerdo da tela) para o IBAction em seu código
Brad Root
É bom observar que arrastar diretamente do campo de texto no storyboard padronizará a ação vinculada para Edição finalizada, em vez de Ação primária acionada, portanto, isso deve ser feito no Inspetor de conexões da barra lateral.
Cloud
Surpreendente. Eu não sabia disso. Obrigado.
Numan Karaaslan
Também funciona com o Swift 2, se alguém ainda se importa. Obrigado.
siralexsir88
22

Solução Simple Swift 3: Adicione esta função aos controladores de exibição que apresentam um campo de texto:

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

Em seguida, abra o editor assistente e verifique se o Main.storyboard está em um lado da sua visualização e o arquivo controller.swift da visualização desejado está no outro. Clique em um campo de texto e selecione no painel de utilitários do lado direito a guia 'Mostrar o Inspetor de Conexão'. Arraste a tecla Control de 'Terminou ao sair' para a função acima no seu arquivo rápido. Repita o procedimento para qualquer outro campo de texto nessa cena e vincule à mesma função.

elarcoiris
fonte
14

@RSC

para mim, a adição crítica no Xcode Versão 6.2 (6C86e) está em override func viewDidLoad()

 self.input.delegate = self;

Tentei fazê-lo funcionar com a chave de retorno por horas até encontrar sua postagem, RSC. Obrigado!

Além disso, se você deseja ocultar o teclado, se tocar em qualquer outro lugar na tela:

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

Para obter a dispensa automática do teclado, coloquei esse código em um dos métodos da classe do meu campo de texto personalizado:

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

Substitua o nome da sua tomada por textField.

peacetype
fonte
1
Excepcional. Esta é a opção mais curta e melhor na minha opinião. Especialmente quando você está criando um campo de texto dentro de outro método. Como dentro de um cabeçalho de exibição de tabela.
precisa saber é
Desculpe, onde exatamente você deve colocar isso e o que você precisa fazer para fechar o teclado? Coloquei mytextfield.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)(versão Swift 5) em, viewDidLoadmas nem retornei nem toquei em algum lugar fora do campo de texto funcionou. Eu consegui os campos de texto criando uma saída cada.
Neph 27/06/19
Coloquei-o em uma subclasse de uma classe personalizada que herda de UIViewController. A subclasse também está em conformidade com UITextViewDelegate e UITextFieldDelegate. Eu coloquei no viewDidAppearmétodo dessa classe. UIAlertController.addTextField(configurationHandler: {(textField: UITextField!) in textField.delegate = self textField.addTarget(self, action: #selector(MySubclass.textChanged(_:)), for: .editingChanged) })Isso pode ser um pouco específico demais para o meu caso, mas espero que ajude. Tente fazer a ligação dentro viewDidAppeare em conformidade com os delegados, se necessário.
peacetype 27/06/19
10

Outra maneira de fazer isso que usa principalmente o storyboard e permite facilmente que você tenha vários campos de texto é:

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

Conecte todos os seus campos de texto para esse controlador de exibição a essa ação no Did End On Exitevento de cada campo.

James Thompson
fonte
Desculpe o problema, mas estou tentando esse método no meu aplicativo e ele não parece estar funcionando. Eu tenho um campo de texto na barra de navegação e o conectei a essa ação com esse evento, como você disse, mas não funciona em tempo de execução.
wasimsandhu
Isso falharia se o remetente fosse do tipo UIBarButtonItem. Se eu adicionar barra de ferramentas com o botão Concluído ao teclado numérico, seu código poderá falhar com o seletor não reconhecido enviado ao log da instância.
Jayprakash Dubey
8

Eu sugeriria iniciar a classe do 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
fonte
8

Quando o usuário toca no botão Concluído no teclado de texto, um evento Terminou ao sair será gerado; nesse momento, precisamos dizer ao campo de texto para abrir mão do controle para que o teclado desapareça. Para fazer isso, precisamos adicionar um método de ação à nossa classe de controlador. Selecione ViewController.swift e adicione o seguinte método de ação:

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

Selecione Main.storyboard no Project Navigator e abra o inspetor de conexões. Arraste do círculo ao lado de Terminou ao sair para o ícone amarelo do View Controller no storyboard e solte-o. Um pequeno menu pop-up aparecerá, contendo o nome de uma única ação, a que acabamos de adicionar. Clique na ação textFieldDoneEditing para selecioná-lo e pronto.

Ian Seth Colin
fonte
8

Aqui está a atualização do Swift 3.0 para o comentário do peacetype:

textField.addTarget(nil, action:Selector(("firstResponderAction:")), for:.editingDidEndOnExit)
Darth Flyeater
fonte
esta é uma resposta limpa
po5i 28/02
Essa deve ser a resposta aceita. Trabalhou em uma única tentativa.
Jaswant Singh
7

Detesto adicionar a mesma função a todos os UIViewController. Estendendo o UIViewController para oferecer suporte ao UITextFieldDelegate, você pode fornecer um comportamento padrão de "retorno pressionado".

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

Quando você cria novos UIViewController e UITextField, tudo o que você precisa fazer é escrever um código de linha no seu UIViewController.

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

Você pode até omitir esse código de uma linha conectando delegate no Main.storyboard. (Usando "ctrl" e arraste de UITextField para UIViewController)

Wu Yuan Chun
fonte
5

Swift 3

Adicione este código abaixo ao seu 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 mim

Gilad Brunfman
fonte
3

Verifique se o seu delegado textField está definido como o controlador de exibição no qual você está escrevendo seu código relacionado ao campo de texto.

self.textField.delegate = self
Miladinho
fonte
3

Rápido

Usando a função opcional de UITextFieldDelegate.

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

falsesignifica que esse campo pode ser solicitado a renunciar. true- forçar demissão.

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

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

então você usa esta função

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

você pode colocar isso em qualquer lugar, mas não em um UIButton

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

então você pode colocar esse código em um botão (também por exemplo):

self.view.endEditing(true)

isso funcionou para mim

Blake Scott
fonte
2

No controlador de exibição que você está usando:

//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
fonte
Eu gosto da função touchesBegan, funciona no swift 4 obrigado.
AJ Hernandez
-1

você deve conectar o UITextfied a um controlador de delegado de visão para tornar essa função chamada

Abdulrahman Masoud
fonte
-1

Tudo em um ocultar o teclado e mover a exibição no teclado aberto: 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
fonte