So che devo dire al mio UITextField di dare le dimissioni dal primo risponditore quando desidero smantellare la tastiera, ma non sono sicuro di sapere quando l'utente ha premuto il tasto "Fine" sulla tastiera. C'è una notifica che posso cercare?
So che devo dire al mio UITextField di dare le dimissioni dal primo risponditore quando desidero smantellare la tastiera, ma non sono sicuro di sapere quando l'utente ha premuto il tasto "Fine" sulla tastiera. C'è una notifica che posso cercare?
Risposte:
Ho impostato il delegato della UITextField
mia ViewController
classe.
In quella classe ho implementato questo metodo come segue:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
NO
invece di YES
?
NO
si evita di aggiungere una riga di ritorno al testo.
Se si collega l'evento DidEndOnExit del campo di testo a un'azione (IBAction) in InterfaceBuilder, verrà inviato un messaggio quando l'utente elimina la tastiera (con il tasto Invio) e il mittente sarà un riferimento all'UITextField che ha generato l'evento.
Per esempio:
-(IBAction)userDoneEnteringText:(id)sender
{
UITextField theField = (UITextField*)sender;
// do whatever you want with this text field
}
Quindi, in InterfaceBuilder, collega l'evento DidEndOnExit del campo di testo a questa azione sul controller (o qualunque cosa tu stia utilizzando per collegare eventi dall'interfaccia utente). Ogni volta che l'utente inserisce il testo e chiude il campo di testo, al controller verrà inviato questo messaggio.
Puoi anche creare un metodo nel tuo controller
-(IBAction)editingEnded:(id)sender{
[sender resignFirstResponder];
}
e quindi in Connection Inspector in IB connect Evento "Did End On Exit".
DidEndOnExit
all'evento, non è necessario chiamare resignFirstResponder
. Puoi provarlo inserendo un breakpoint simbolico [UIResponder resignFirstResponder]
. Si noti che anche se non si chiama resignFirstResponder, viene comunque chiamato dal sistema. Questo è spiegato negli eccellenti libri di Matt Neuburg: apeth.com/iOSBook/…
kubi, grazie. Il tuo codice ha funzionato. Giusto per essere esplicito (per i neofiti come) mentre dici che devi impostare UITextField
's delegate
in modo che sia uguale al ViewController in cui risiede il campo di testo. Puoi farlo ovunque tu voglia. Ho scelto il viewDidLoad
metodo
- (void)viewDidLoad
{
// sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
daTextField.delegate = self;
}
delegate
lì. Non è necessario farlo a livello di codice, come dimostrato sopra. Entrambi gli approcci funzionano bene.
Ecco un trucco per ottenere il comportamento di licenziamento automatico della tastiera senza alcun codice. Nel pennino, modificare l'oggetto proxy First Responder nella finestra di ispezione Identity, aggiungendo una nuova azione first responder; chiamiamolo dummy:
. Ora aggancia l'evento Did End on Exit del campo di testo dummy:
all'azione dell'oggetto proxy First Responder. Questo è tutto! Poiché l'evento Did End on Exit del campo di testo ora ha una coppia azione-bersaglio, il campo di testo elimina automaticamente la sua tastiera quando l'utente tocca Return; e poiché non vi è alcuna penalità per non aver trovato un gestore per un messaggio inviato nella catena di risponditori, l'app non si arresta in modo anomalo anche se non è stata implementata alcuna applicazione dummy:
.
Basta aggiungere
[textField endEditing:YES];
dove si desidera disabilitare la tastiera e visualizzare la vista selettore.
In Swift puoi scrivere un'IBAction nel controller e impostare l' evento Did End On Exit del campo di testo su quell'azione
@IBAction func returnPressed(sender: UITextField) {
self.view.endEditing(true)
}
Swift 4.2
e funzionerà al 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
}
}
Puoi anche usare
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.yourTextField resignFirstResponder];
}
Il migliore se hai molti Uitextfields:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
Ecco cosa ho dovuto fare per farlo funzionare, e penso che sia necessario per chiunque abbia un tastierino numerico per una tastiera (o qualsiasi altro senza un pulsante fatto:
Ho creato una funzione chiamata
-(IBAction)backgroundIsTapped:(id)sender
Questo è stato anche definito nel file .h.
Successivamente, mi sono collegato al bit 'touch down' per ViewController in Interface Builder.
Nella funzione 'background is tapped', ho messo questo:
[answerField resignFirstResponder];
Ricorda solo di cambiare 'answerField' con il nome di UITextField da cui vuoi rimuovere la tastiera (ovviamente assicurati che UITextField sia definito come sotto :)
IBOutlet UITextField * <nameoftextfieldhere>;
So che questo argomento probabilmente è morto molto tempo fa ... ma spero che questo possa aiutare qualcuno, da qualche parte!
Noterai che il metodo "textFieldShouldReturn" fornisce l'oggetto campo di testo che ha premuto il tasto DONE. Se si imposta il TAG è possibile attivare quel campo di testo. Oppure puoi tenere traccia e confrontare il puntatore dell'oggetto con un valore del membro memorizzato dal suo creatore.
Il mio approccio è così per uno studio autonomo:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
bool fDidResign = [textField resignFirstResponder];
NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");
return fDidResign;
}
Nel frattempo, ho inserito il test di "convalida" che nega le dimissioni che seguono. È solo a scopo illustrativo, quindi se l'utente digita NO! nel campo, non verrà respinto. Il comportamento era come volevo, ma la sequenza di output non era come mi aspettavo.
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
NSLog(@"%s", __FUNCTION__);
if( [[textField text] isEqualToString:@"NO!"] ) {
NSLog(@"%@", textField.text);
return NO;
} else {
return YES;
}
}
Di seguito è riportato il mio output NSLog per questo rifiuto seguito dall'accettazione. Noterai che sto restituendo il risultato delle dimissioni, ma mi aspettavo che restituisse FALSO a me per riferire al chiamante ?! Oltre a ciò, ha il comportamento necessario.
13.313 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:] 13.320 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:] 13.327 StudyKbd [109: 207] NO! 13.333 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: ha rassegnato le dimissioni dalla tastiera 59.891 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:] 59.897 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:] 59.917 StudyKbd [109: 207] - [StudyKbdViewController doneEditText]: NO 59.928 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: ha rassegnato le dimissioni dalla tastiera
Ecco un modo abbastanza semplice per terminare l'edizione con il tasto Invio o un tocco in background.
Nel builder Interface, incorporare i campi in una vista della classe UIFormView
Cosa significa questa classe:
Ecco il codice:
Interfaccia
#import <UIKit/UIKit.h>
@interface UIFormView : UIView<UITextFieldDelegate>
-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;
@end
Implementazione
#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
Sottoclassando il modulo e sovrascrivendo il
textFieldValueIsValid:
metodo, è possibile evitare la fine dell'edizione se il valore non è corretto per il campo dato.
Se un campo ha un delegato impostato in Interface Builder, il modulo non lo modifica. Non vedo molte ragioni per impostare un delegato diverso in un determinato campo, ma perché no ...
Esistono molti modi per migliorare questa classe di visualizzazione dei moduli: allegare un delegato, eseguire alcuni layout, gestire quando le tastiere coprono un campo (utilizzando il frame currentEditingTextField), avviare automaticamente l'edizione per il campo successivo, ...
Personalmente lo tengo nel mio framework e lo faccio sempre sottoclasse per aggiungere funzionalità, è abbastanza spesso utile "così com'è".
Spero che possa aiutare. Saluti a tutti
se vuoi tutte le modifiche in un UIViewController puoi usare.
[[self view]endEditing:YES];
e se vuoi scartare una tastiera per tastiera UITextField perticolare, usa.
1.aggiungi delegato nel tuo viewcontroller.h
<UITextFieldDelegate>
rendere la delega impossibile per il tuo campo di testo.
self.yourTextField.delegate = self;
aggiungi questo metodo al tuo viewcontroller.
- (BOOL) textFieldShouldEndEditing: (UITextField *) textField {[textField resignFirstResponder]; restituire SÌ;}
Impostare programmaticamente il delegato di UITextField in swift 3
Implementa UITextFieldDelegate nel tuo file ViewController.Swift (ad es. 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: - gestione del delegato 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
}
Crea una funzione hidekeyboard e collegala al campo di testo nel file .xib e seleziona DidEndOnExit
-(IBAction)Hidekeyboard
{
textfield_name.resignFirstResponder;
}
Se hai creato la vista utilizzando Interface Builder, utilizza quanto segue Basta creare un metodo,
-(IBAction)dismissKeyboard:(id)sender
{
[sender resignFirstResponder];
}
Basta fare clic con il tasto destro del mouse sul campo di testo nella vista, impostare l'evento come Did End on Exit e collegarlo al metodo "dismissKeyboard".
La migliore guida per i principianti è "Head First iPhone and iPad Development, 2nd Edition"
prova questo
- (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;
}
Chiunque cerchi Swift 3
1) Assicurati che il delegato di UITextField sia collegato al ViewController nello Storyboard
2) Implementare UITextFieldDelegate nel file ViewController.Swift (ad es. Class ViewController: UIViewController, UITextFieldDelegate {)
3) Utilizzare il metodo delegato di seguito
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false }
Ecco come licenzio la tastiera in Swift 4.2 e funziona per me:
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+
@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}
UPD: Funziona ancora bene per me. Penso che il ragazzo che ha dedicato questa risposta non abbia capito che deve legare questa azione a UITextField nello storyboard.