Wie schließen Sie die Tastatur beim Bearbeiten eines UITextField?


181

Ich weiß, dass ich meinem UITextField mitteilen muss, dass der Ersthelfer zurücktreten soll, wenn ich die Tastatur deaktivieren möchte, aber ich bin nicht sicher, wie ich wissen soll, wann der Benutzer die Taste "Fertig" auf der Tastatur gedrückt hat. Gibt es eine Benachrichtigung, auf die ich achten kann?


2
[self.view endEditing: YES]; in Berührungen begann Delegierter ist die beste Lösung
Zar E Ahmer

Antworten:


351

Ich setze den Delegierten der UITextFieldin meine ViewControllerKlasse.

In dieser Klasse habe ich diese Methode wie folgt implementiert:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return NO;
}

Sehen Sie sich das obige Beispiel an ... verbinden Sie die Verwendung von IntefaceBuilder mit der Aktion für alles, was Sie als Controller verwenden ... wenn der Benutzer das Texteingabesystem schließt (Drücken Sie erledigt), wird dies aufgerufen ...
Jason Coco

2
Beides funktioniert - das Textfeld sendet seine Aktion, wenn der Benutzer die Eingabetaste ("Fertig", was auch immer) drückt, und sendet auch seinen Delegaten -textFieldShouldReturn:.
Noah Witherspoon

Übrigens - dies funktioniert auch für eine UISearchBar. Zum Beispiel hatte mein Code ein Mitglied IBOutlet searchBarTusb; Als mein 'Return Key' (UIReturnKeySearch) angeklickt wurde, - (void) searchBarSearchButtonClicked:, habe ich die Anweisung [searchBarTusb resignFirstResponder] eingefügt; Beachten Sie auch, dass der 'Return Key' in der NIB mit Interface Builder festgelegt wurde.
Mobibob

Warum zurückkehren NOstatt YES?
Iulian Onofrei

@IulianOnofrei Das Standardverhalten der Schaltfläche "Zurück" besteht darin, eine Zeilenrückgabe hinzuzufügen und die Tastatur auf dem Bildschirm zu halten. Durch die Rückgabe NOvermeiden Sie, dem Text eine Zeilenrückgabe hinzuzufügen.
Kubi

47

Wenn Sie das DidEndOnExit-Ereignis des Textfelds mit einer Aktion (IBAction) in InterfaceBuilder verbinden, wird eine Nachricht gesendet, wenn der Benutzer die Tastatur schließt (mit der Eingabetaste) und der Absender ein Verweis auf das UITextField ist, das das Ereignis ausgelöst hat.

Beispielsweise:

-(IBAction)userDoneEnteringText:(id)sender
{
    UITextField theField = (UITextField*)sender;
    // do whatever you want with this text field
}

Verknüpfen Sie dann in InterfaceBuilder das DidEndOnExit-Ereignis des Textfelds mit dieser Aktion auf Ihrem Controller (oder was auch immer Sie zum Verknüpfen von Ereignissen über die Benutzeroberfläche verwenden). Immer wenn der Benutzer Text eingibt und das Textfeld schließt, wird dem Controller diese Nachricht gesendet.


Das einzige Ereignis, das anscheinend funktioniert, ist textFieldDidEndEditing, das angibt, dass es erst gesendet wird, nachdem UITextField den Ersthelferstatus niedergelegt hat. Woher weiß ich, wann ich den Ersthelferstatus niederlegen muss?
Kubi

Es tut mir leid wegen der Terminologie ... es ist keine tatsächliche Benachrichtigung (Ereignis) ... Ich werde meine Antwort mit einem kurzen Beispiel und einer Erklärung bearbeiten, also sehen Sie das :)
Jason Coco

1
Um diese Antwort zu verdeutlichen, sendet das textField das Ereignis "Did End On Exit", wenn Sie die Eingabetaste drücken. Dies ist also das Ereignis, das Sie mit Ihrem Controller verknüpfen müssen. Ich denke, diese Methode ist einfacher als die oben beschriebene.
Kubi

2
Könnten Sie diese Antwort so bearbeiten, dass darin erwähnt wird, welches Ereignis zu verkabeln ist? Dies ist offensichtlich schöner als das Setzen des Delegierten.
Dan Rosenstark

1
Sie möchten diese Antwort positiv bewerten, können dies jedoch erst tun, wenn das DidEndOnExit-Ereignis erwähnt wird. Jemand mit Bearbeitungsrechten nimmt bitte die Änderung vor, wenn das OP dies nicht tut.
James Hart

32

Sie können auch eine Methode in Ihrem Controller erstellen

 -(IBAction)editingEnded:(id)sender{
    [sender resignFirstResponder]; 
}

und dann im Verbindungsinspektor in IB das Ereignis "Did End On Exit" damit verbinden.


1
Dies ist fast falsch oder verfehlt zumindest den Punkt. Wenn Sie die DidEndOnExitVeranstaltung abonnieren , müssen Sie nicht anrufen resignFirstResponder. Sie können dies testen, indem Sie einen symbolischen Haltepunkt setzen [UIResponder resignFirstResponder]. Beachten Sie, dass auch wenn Sie resignFirstResponder nicht aufrufen, es vom System aufgerufen wird. Dies wird in Matt Neuburgs hervorragenden Büchern erklärt: apeth.com/iOSBook/…
Chris Conover

19

Kubi, danke. Ihr Code hat funktioniert. Nur explizit zu sein (für Neulinge mögen) , wie Sie sagen , dass Sie die eingestellte müssen UITextField‚s delegateauf die Viewcontroller , in dem das Textfeld wohnt gleich sein. Sie können dies tun, wo immer Sie möchten. Ich habe die viewDidLoadMethode gewählt.

- (void)viewDidLoad 
{
    // sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
    daTextField.delegate = self;
}

Wenn Sie Ihrem Storyboard oder Ihrer NIB ein Textfeld hinzugefügt haben, können Sie dort auch die Textfelder festlegen delegate. Sie müssen dies nicht programmgesteuert tun, wie oben gezeigt. Jeder Ansatz funktioniert gut.
Rob

18

Hier ist ein Trick, um ein automatisches Tastaturentlassungsverhalten ohne Code zu erhalten. Bearbeiten Sie in der Schreibfeder das First-Responder-Proxy-Objekt im Identitätsinspektor und fügen Sie eine neue First-Responder-Aktion hinzu. Nennen wir es dummy:. Verknüpfen Sie nun das Ereignis Did End on Exit des Textfelds mit der dummy:Aktion des First Responder-Proxy-Objekts. Das ist es! Da das Ereignis Did End on Exit des Textfelds jetzt ein Aktions-Ziel-Paar enthält, wird die Tastatur des Textfelds automatisch geschlossen, wenn der Benutzer auf Return tippt. und da es keine Strafe gibt, wenn kein Handler für eine Nachricht gefunden wird, die über die Responderkette gesendet wird, stürzt die App nicht ab, obwohl dummy:nirgendwo eine Implementierung vorhanden ist.


@matt Ich habe festgestellt, dass, wenn ich einen Abwicklungsbereich hinzufüge UND das didEndOnExit-Ereignis verbinde, der Abwicklungsabschnitt beim Drücken der Eingabetaste ausgelöst wird. Ohne die Ereignisverbindung wird der Übergang nicht ausgelöst. Großartig, aber nicht wahr? Irgendwelche Bemerkungen? Übrigens: Ich habe Ihre Bücher Swift (fertig) und iOS10 (Kapitel 6). Sie haben mir enorm geholfen!
Verticon

@Verticon Die Frage und Antwort hat nichts mit Segues zu tun, daher verstehe ich das Problem nicht ... :( Hier geht es nur um die Entlassung der Tastatur
Matt

@ Matt Entschuldigung, Mann. Ich habe Huckepack genommen, weil 1) ich auf diesen Thread gestoßen bin, als ich mich mit dem Umgang mit der Eingabetaste des UITextField befasst habe; und 2) es war eine Gelegenheit mit dir zu interagieren (danke für die Bücher). Es gibt kein "Problem". Nur ein Mangel an Verständnis meinerseits darüber, warum / wie es so funktioniert, wie es funktioniert.
Verticon

@Verticon Ich entschuldige mich dafür, dass ich nicht helfen kann. Fühlen Sie sich frei, eine neue Frage mit mehr Informationen zu formulieren (Demo-Projekt?) Und mich zu blippen, wenn ich nützlich sein kann.
Matt


11

Einfach hinzufügen

[textField endEditing:YES];

Hier möchten Sie die Tastatur deaktivieren und die Auswahlansicht anzeigen.


10

In Swift können Sie eine IBAction in den Controller schreiben und das Ereignis Did End On Exit des Textfelds auf diese Aktion setzen

@IBAction func returnPressed(sender: UITextField) {
    self.view.endEditing(true)
}

5

Swift 4.2 und es wird 100% funktionieren

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
    }

}

4

Sie können auch verwenden

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
  {

   [self.yourTextField resignFirstResponder];

  }

Am besten, wenn Sie viele Uitextfelder haben:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {    
     [self.view endEditing:YES];
 }

2

Folgendes musste ich tun, damit es funktioniert, und ich denke, dass dies für jeden erforderlich ist, der einen Nummernblock für eine Tastatur hat (oder für andere ohne eine Schaltfläche "Fertig":

  1. Ich habe die UIView im ViewController in eine UIControl geändert.
  2. Ich habe eine Funktion namens erstellt

    -(IBAction)backgroundIsTapped:(id)sender

Dies wurde auch in der .h-Datei definiert.

Danach habe ich im Interface Builder eine Verknüpfung zum Touchdown-Bit für den ViewController hergestellt.

In die Funktion 'Hintergrund wird getippt' habe ich Folgendes eingefügt:

    [answerField resignFirstResponder];

Denken Sie daran, 'answerField' in den Namen des UITextField zu ändern, von dem Sie die Tastatur entfernen möchten (stellen Sie natürlich sicher, dass Ihr UITextField wie unten definiert ist :)

    IBOutlet UITextField * <nameoftextfieldhere>;

Ich weiß, dass dieses Thema wahrscheinlich vor langer Zeit gestorben ist ... aber ich hoffe, dass dies irgendwo jemandem hilft!


..aber es funktioniert nicht so gut, wenn der Benutzer auf ein anderes Steuerelement tippt.
Ragnarius

2

Sie werden feststellen, dass die Methode "textFieldShouldReturn" das Textfeldobjekt bereitstellt, das die Taste DONE gedrückt hat. Wenn Sie den TAG einstellen, können Sie dieses Textfeld einschalten. Oder Sie können den Zeiger des Objekts verfolgen und mit einem vom Ersteller gespeicherten Elementwert vergleichen.

Mein Ansatz für ein Selbststudium ist wie folgt:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"%s", __FUNCTION__);

    bool fDidResign = [textField resignFirstResponder];

    NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");

    return fDidResign;
}

In der Zwischenzeit habe ich den "Validierungstest" durchgeführt, der den folgenden Rücktritt leugnet. Es dient nur zur Veranschaulichung. Wenn der Benutzer also NO! in das Feld wird es nicht entlassen. Das Verhalten war wie ich wollte, aber die Reihenfolge der Ausgabe war nicht wie ich erwartet hatte.

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    NSLog(@"%s", __FUNCTION__);

    if( [[textField text] isEqualToString:@"NO!"] ) {
        NSLog(@"%@", textField.text);
        return NO;
    } else {
        return YES;
    }
}

Es folgt meine NSLog-Ausgabe für diese Ablehnung, gefolgt von der Annahme. Sie werden feststellen, dass ich das Ergebnis des Rücktritts zurücksende, aber ich habe erwartet, dass es FALSE an mich zurücksendet, um dem Anrufer Bericht zu erstatten?! Davon abgesehen hat es das notwendige Verhalten.

13.313 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]
13.320 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldEndEditing:]
13.327 StudyKbd [109: 207] NEIN!
13.333 StudyKbd [109: 207] - [StudyKbdViewController textFieldShouldReturn:]: hat die Tastatur verlassen
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:]: hat die Tastatur verlassen

1
Kannst du erklären ..wenn ich NEIN oder JA zurückgebe, passieren in beiden Fällen die gleichen Dinge, also was ist die Notwendigkeit, Ja in textFieldShouldReturn-Delegatenmethode zurückzugeben
K. Jaiswal

1

Hier ist eine recht saubere Möglichkeit, die Ausgabe mit der Eingabetaste oder einer Berührung im Hintergrund zu beenden.

Betten Sie im Interface Builder Ihre Felder in eine Ansicht der Klasse UIFormView ein

Was macht diese Klasse:

  • Hängt sich automatisch als Delegat für Felder an (entweder von der Feder geweckt oder manuell hinzugefügt)
  • Behalten Sie einen Verweis auf das aktuell bearbeitete Feld
  • Schließen Sie die Tastatur bei der Rückkehr oder berühren Sie sie im Hintergrund

Hier ist der Code:

Schnittstelle

#import <UIKit/UIKit.h>

@interface UIFormView : UIView<UITextFieldDelegate>

-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;

@end

Implementierung

#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
  • Durch Unterklassen des Formulars und Überschreiben der textFieldValueIsValid:Methode können Sie das Ende der Ausgabe vermeiden, wenn der Wert für das angegebene Feld nicht korrekt ist.

  • Wenn für ein Feld in Interface Builder ein Delegat festgelegt ist, ändert das Formular dies nicht. Ich sehe nicht viele Gründe, einen anderen Delegierten für ein bestimmtes Feld zu bestimmen, aber warum nicht ...

Es gibt viele Möglichkeiten, diese Formularansichtsklasse zu verbessern: Fügen Sie einen Delegaten hinzu, führen Sie ein Layout durch, behandeln Sie, wenn die Tastatur ein Feld abdeckt (unter Verwendung des aktuellen EditingTextField-Rahmens), starten Sie die Edition automatisch für das nächste Feld, ...

Ich persönlich behalte es in meinem Framework und unterteile es immer, um Funktionen hinzuzufügen. Es ist ziemlich oft nützlich, "wie es ist".

Ich hoffe es wird helfen. Prost alle


1
Hilfreiche Klasse. Ein kleiner Punkt: Sie sollten Ihren eigenen Klassen nicht "UI" voranstellen. In Objective-C sollten Sie Ihr eigenes Präfix ("TL"?) Verwenden, in Swift nichts.
Kubi

Danke @kubi. Das stimmt. Es ist MF in meinem Rahmen, wie MooseFactory;)
Moose

1

Wenn Sie alle Bearbeitungen in einem UIViewController durchführen möchten, können Sie diese verwenden.

[[self view]endEditing:YES];

und wenn Sie eine bestimmte UITextField-Tastatur ausblenden möchten, verwenden Sie.

1.add delegate in your viewcontroller.h

<UITextFieldDelegate>
  1. Deaktivieren Sie die Delegierung für Ihr Textfeld.

    self.yourTextField.delegate = self;

  2. Fügen Sie diese Methode Ihrem Viewcontroller hinzu.

    - (BOOL) textFieldShouldEndEditing: (UITextField *) textField {[textField resignFirstResponder]; JA zurückgeben;}


1

Setzen Sie den Delegaten des UITextField programmgesteuert auf Swift 3

Implementieren Sie UITextFieldDelegate in Ihrer ViewController.Swift-Datei (z. B. Klasse 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: - Umgang mit delegierten 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
}

0

Erstellen Sie eine Funktion hidekeyboard, verknüpfen Sie sie mit dem Textfeld in der .xib-Datei und wählen Sie DidEndOnExit aus

-(IBAction)Hidekeyboard    
{    
      textfield_name.resignFirstResponder;    
}  

0

Wenn Sie die Ansicht mit dem Interface Builder erstellt haben, verwenden Sie Folgendes: Erstellen Sie einfach eine Methode:

-(IBAction)dismissKeyboard:(id)sender
{
[sender resignFirstResponder];
}

Klicken Sie einfach mit der rechten Maustaste auf das Textfeld in der Ansicht, setzen Sie das Ereignis als "Beim Beenden beendet" und verbinden Sie es mit der Methode "acceptKeyboard".

Der beste Leitfaden für Anfänger ist "Head First iPhone- und iPad-Entwicklung, 2. Ausgabe".


0

Versuche dies

- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
    if ([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}

0
//====================================================
//                  textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField { 
    [textField resignFirstResponder];
    if(textField.returnKeyType != UIReturnKeyDone){
        [[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
    }
    return YES;
}

0

Wer Swift 3 sucht

1) Stellen Sie sicher, dass der Delegat Ihres UITextField mit Ihrem ViewController im Storyboard verbunden ist

2) Implementieren Sie UITextFieldDelegate in Ihrer ViewController.Swift-Datei (z. B. Klasse ViewController: UIViewController, UITextFieldDelegate {)

3) Verwenden Sie die unten stehende Delegate-Methode

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

0

So entlasse ich die Tastatur in Swift 4.2 und es funktioniert für mich:

    override func viewDidLoad() {
    super.viewDidLoad()

    let tap = UITapGestureRecognizer(target: self, action: 
    #selector(dismissKeyboard))

    view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    numberField.resignFirstResponder()
    }

-2

Swift 3, iOS 9+

@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}

UPD: Es funktioniert immer noch gut für mich. Ich denke, der Typ, der diese Antwort gewidmet hat, hat einfach nicht verstanden, dass er diese Aktion an das UITextField im Storyboard binden muss.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.