Sei que preciso solicitar ao meu UITextField que renuncie ao primeiro atendedor quando quiser desligar o teclado, mas não sei como saber quando o usuário pressionou a tecla "Concluído" no teclado. Existe uma notificação que eu possa assistir?
Sei que preciso solicitar ao meu UITextField que renuncie ao primeiro atendedor quando quiser desligar o teclado, mas não sei como saber quando o usuário pressionou a tecla "Concluído" no teclado. Existe uma notificação que eu possa assistir?
Respostas:
Eu coloquei o delegado da na UITextField
minha ViewController
classe.
Nessa classe, implementei esse método da seguinte maneira:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
NO
vez de YES
?
NO
você evita adicionar um retorno de linha ao texto.
Se você conectar o evento DidEndOnExit do campo de texto a uma ação (IBAction) no InterfaceBuilder, ele receberá uma mensagem quando o usuário dispensar o teclado (com a tecla Enter) e o remetente será uma referência ao UITextField que acionou o evento.
Por exemplo:
-(IBAction)userDoneEnteringText:(id)sender
{
UITextField theField = (UITextField*)sender;
// do whatever you want with this text field
}
Em seguida, no InterfaceBuilder, vincule o evento DidEndOnExit do campo de texto a esta ação no seu controlador (ou o que você estiver usando para vincular eventos da interface do usuário). Sempre que o usuário digitar texto e dispensar o campo de texto, o controlador receberá esta mensagem.
Você também pode criar um método no seu controlador
-(IBAction)editingEnded:(id)sender{
[sender resignFirstResponder];
}
e, em seguida, no Connection Inspector no IB, conecte o evento "Terminou na saída" a ele.
DidEndOnExit
evento, você não precisa ligar resignFirstResponder
. Você pode testar isso colocando um ponto de interrupção simbólico [UIResponder resignFirstResponder]
. Observe que, mesmo se você não chamar resignFirstResponder, ele ainda será chamado pelo sistema. Isso é explicado pelos excelentes livros de Matt Neuburg: apeth.com/iOSBook/…
kubi, obrigado. Seu código funcionou. Só para ser explícito (para iniciantes gosta) como você diz que você tem que definir o UITextField
's delegate
para ser igual ao ViewController em que reside o campo de texto. Você pode fazer isso onde quiser. Eu escolhi o viewDidLoad
método
- (void)viewDidLoad
{
// sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
daTextField.delegate = self;
}
delegate
. Você não precisa fazer isso programaticamente, conforme demonstrado acima. Qualquer abordagem funciona bem.
Aqui está um truque para obter o comportamento automático de dispensa de teclado sem nenhum código. Na ponta, edite o objeto proxy do Primeiro Respondente no Inspetor de Identidade, adicionando uma nova ação do Primeiro Respondente; vamos chamá-lo dummy:
. Agora conecte o evento Terminou na saída do campo de texto à dummy:
ação do objeto proxy do Primeiro Respondente. É isso aí! Como o evento Terminou na saída do campo de texto agora tem um par de ação-destino, o campo de texto automaticamente dispensa o teclado quando o usuário toca em Retornar; e como não há penalidade por não encontrar um manipulador para uma mensagem enviada na cadeia de respostas, o aplicativo não falha, mesmo que não haja implementação em dummy:
nenhum lugar.
Basta adicionar
[textField endEditing:YES];
onde você deseja desativar o teclado e exibir a exibição do seletor.
No Swift, você pode escrever uma IBAction no Controller e definir o evento Did End On Exit do campo de texto para essa ação
@IBAction func returnPressed(sender: UITextField) {
self.view.endEditing(true)
}
Swift 4.2
e funcionará 100%
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
}
// hide key board when the user touches outside keyboard
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
// user presses return key
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
Você também pode usar
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.yourTextField resignFirstResponder];
}
Melhor se você tiver muitos Uitextfields:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
Aqui está o que eu fiz para fazê-lo funcionar, e acho que é necessário para qualquer pessoa com um teclado numérico (ou qualquer outro sem botão pronto):
Eu criei uma função chamada
-(IBAction)backgroundIsTapped:(id)sender
Isso também foi definido no arquivo .h.
Depois disso, vinculei ao bit 'touch down' do ViewController no Interface Builder.
Na função 'background is tapped', coloquei o seguinte:
[answerField resignFirstResponder];
Lembre-se de alterar 'answerField' para o nome do UITextField do qual você deseja remover o teclado (obviamente, verifique se o seu UITextField está definido como abaixo :)
IBOutlet UITextField * <nameoftextfieldhere>;
Eu sei que esse tópico provavelmente morreu há muito tempo ... mas espero que isso ajude alguém, em algum lugar!
Você notará que o método "textFieldShouldReturn" fornece o objeto de campo de texto que pressionou a tecla DONE. Se você definir o TAG, poderá ativar esse campo de texto. Ou você pode acompanhar e comparar o ponteiro do objeto com algum valor de membro armazenado por seu criador.
Minha abordagem é assim para um auto-estudo:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
bool fDidResign = [textField resignFirstResponder];
NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");
return fDidResign;
}
Enquanto isso, coloquei o teste de "validação" que nega a renúncia. É apenas para ilustração, portanto, se o usuário digitar NÃO! no campo, não será descartado. O comportamento era como eu queria, mas a sequência de saída não era como eu esperava.
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
if( [[textField text] isEqualToString:@"NO!"] ) {
NSLog(@"%@", textField.text);
return NO;
} else {
return YES;
}
}
A seguir, minha saída do NSLog para essa negação, seguida pela aceitação. Você notará que estou retornando o resultado da demissão, mas eu esperava que ela retornasse FALSE para que eu denunciasse o chamador ?! Fora isso, ele tem o comportamento necessário.
13.313 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:] 13.320 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:] 13.327 StudyKbd [109: 207] NÃO! 13.333 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: renunciou ao teclado 59.891 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:] 59.897 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:] 59.917 StudyKbd [109: 207] - [StudyKbdViewController doneEditText]: NÃO 59.928 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: renunciou ao teclado
Aqui está uma maneira bastante clara de finalizar a edição com a tecla Return ou com um toque em segundo plano.
No construtor Interface, incorpore seus campos em uma exibição da classe UIFormView
O que essa classe:
Aqui está o código:
Interface
#import <UIKit/UIKit.h>
@interface UIFormView : UIView<UITextFieldDelegate>
-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;
@end
Implementação
#import "UIFormView.h"
@implementation UIFormView
{
UITextField* currentEditingTextField;
}
// Automatically register fields
-(void)addSubview:(UIView *)view
{
[super addSubview:view];
if ([view isKindOfClass:[UITextField class]]) {
if ( ![(UITextField*)view delegate] ) [(UITextField*)view setDelegate:self];
}
}
// UITextField Protocol
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
currentEditingTextField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
currentEditingTextField = NULL;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self endEdit];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if ([self textFieldValueIsValid:textField]) {
[self endEdit];
return YES;
} else {
return NO;
}
}
// Own functions
-(void)endEdit
{
if (currentEditingTextField) {
[currentEditingTextField endEditing:YES];
currentEditingTextField = NULL;
}
}
// Override this in your subclass to handle eventual values that may prevent validation.
-(BOOL)textFieldValueIsValid:(UITextField*)textField
{
return YES;
}
@end
Subclassificando o formulário e substituindo o
textFieldValueIsValid:
método, você pode evitar o final da edição se o valor não estiver correto para o campo especificado.
Se um campo tiver um representante definido no Interface Builder, o formulário não o altera. Não vejo muitos motivos para definir um delegado diferente para um campo específico, mas por que não…
Há várias maneiras de melhorar essa classe de exibição de formulário - Anexe um delegado, faça um layout, manipule quando os teclados cobrem um campo (usando o quadro currentEditingTextField), inicie automaticamente a edição para o próximo campo, ...
Pessoalmente, eu o mantenho no meu framework, e sempre o subclasse para adicionar recursos, geralmente é útil "como está".
Espero que ajude. Cheers all
se você quiser toda a edição de um UIViewController, poderá usar.
[[self view]endEditing:YES];
e se você deseja descartar uma ocultação de teclado UITextField em particular, use.
1. adicione delegado no seu viewcontroller.h
<UITextFieldDelegate>
torne a delegação incapaz para o seu campo de texto.
self.yourTextField.delegate = self;
adicione esse método ao seu viewcontroller.
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField {[textField resignFirstResponder]; retornar SIM;}
Defina programaticamente o delegado do UITextField em 3 segundos
Implemente UITextFieldDelegate no seu arquivo ViewController.Swift (por exemplo, classe ViewController: UIViewController, UITextFieldDelegate {)
lazy var firstNameTF: UITextField = {
let firstname = UITextField()
firstname.placeholder = "FirstName"
firstname.frame = CGRect(x:38, y: 100, width: 244, height: 30)
firstname.textAlignment = .center
firstname.borderStyle = UITextBorderStyle.roundedRect
firstname.keyboardType = UIKeyboardType.default
firstname.delegate = self
return firstname
}()
lazy var lastNameTF: UITextField = {
let lastname = UITextField()
lastname.placeholder = "LastName"
lastname.frame = CGRect(x:38, y: 150, width: 244, height: 30)
lastname.textAlignment = .center
lastname.borderStyle = UITextBorderStyle.roundedRect
lastname.keyboardType = UIKeyboardType.default
lastname.delegate = self
return lastname
}()
lazy var emailIdTF: UITextField = {
let emailid = UITextField()
emailid.placeholder = "EmailId"
emailid.frame = CGRect(x:38, y: 200, width: 244, height: 30)
emailid.textAlignment = .center
emailid.borderStyle = UITextBorderStyle.roundedRect
emailid.keyboardType = UIKeyboardType.default
emailid.delegate = self
return emailid
}()
// Mark: - manipulando delegado textField ..
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == firstNameTF {
lastNameTF.becomeFirstResponder()
}
else if textField == lastNameTF {
emailIdTF.becomeFirstResponder()
}
else {
view.emailIdTF(true)
}
return true
}
Crie um hidekeyboard de função e vincule-o ao campo de texto no arquivo .xib e selecione DidEndOnExit
-(IBAction)Hidekeyboard
{
textfield_name.resignFirstResponder;
}
Se você criou a exibição usando o Interface Builder, use o seguinte Basta criar um método,
-(IBAction)dismissKeyboard:(id)sender
{
[sender resignFirstResponder];
}
Apenas clique com o botão direito do mouse no campo de texto na exibição, defina o evento como Terminou ao sair e ligue-o ao método "dispensKeyboard".
O melhor guia para iniciantes é "Head First iPhone and iPad Development, 2nd Edition"
tente isso
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
if ([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
//====================================================
// textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField {
[textField resignFirstResponder];
if(textField.returnKeyType != UIReturnKeyDone){
[[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
}
return YES;
}
Quem procura Swift 3
1) Verifique se o delegado do UITextField está conectado ao seu ViewController no Storyboard
2) Implemente UITextFieldDelegate no seu arquivo ViewController.Swift (por exemplo, classe ViewController: UIViewController, UITextFieldDelegate {)
3) Use o método delegado abaixo
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false }
É assim que eu descarto o teclado no Swift 4.2 e funciona para mim:
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action:
#selector(dismissKeyboard))
view.addGestureRecognizer(tap)
}
@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
numberField.resignFirstResponder()
}
Swift 3, iOS 9 ou superior
@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}
UPD: Ainda funciona bem para mim. Acho que o cara que dedicou essa resposta simplesmente não entendeu que ele precisa vincular essa ação ao UITextField no storyboard.