Schließen Sie die Tastatur, indem Sie den Hintergrund von UITableView berühren


105

Ich habe ein UITableViewmit UITextFields als Zellen. Ich möchte die Tastatur schließen, wenn der Hintergrund des UITableViewberührt wird. Ich versuche dies zu tun, indem ich eine UIButtonGröße von erschaffe UITableViewund sie hinter die lege UITableView. Das einzige Problem ist UIButton, dass alle Berührungen erfasst werden, auch wenn sich die Berührung in der UITableView befindet. Was mache ich falsch?

Vielen Dank!


Wiederholte Fragen und Antworten: Q1 , Q2 , Q3 .
Yantao Xie

Dies ist die beste Antwort stackoverflow.com/a/12851794/1418457
onmyway133

Antworten:


203

Dies ist einfach zu erreichen, indem Sie ein UITapGestureRecognizer- Objekt erstellen (standardmäßig wird eine "Geste" bei einem einzigen Tippen erkannt, sodass keine weitere Anpassung erforderlich ist), ein Ziel / eine Aktion für den Zeitpunkt des Auslösens der Geste angeben und dann das Gestenerkennungsobjekt anhängen zu Ihrer Tabellenansicht.

ZB Vielleicht in Ihrer viewDidLoadMethode:

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];

Und die hideKeyboardMethode könnte so aussehen:

- (void) hideKeyboard {
    [textField1 resignFirstResponder];
    [textField2 resignFirstResponder];
    ...
    ...
}

Beachten Sie, dass die Geste beim Berühren eines UITextFieldObjekts nicht ausgelöst wird. Es wird jedoch im UITableViewHintergrund, in der Fußzeile, in der Kopfzeile und in UILabelsinneren Zellen usw. ausgelöst .


4
Als ich dies versuchte, stellte ich fest, dass die Tabelle keine Zellen auswählen konnte :(. Ansonsten großartige Lösung
Brian

109
Als Lösung unten wird darauf hingewiesen, dass Sie diese Arbeit viel besser machen können, indem Sie gestureRecognizer.cancelsTouchesInView = NO;
Folgendes

3
Vergessen Sie nicht, den gestureRecognizer freizugeben, sobald er an die tableView angehängt ist.
Paul Lynch

39
Für die hideKeyboardMethode können Sie nicht direkt mit den Textfeldern kommunizieren [self.view endEditing:NO];. Aus Apple-Dokumenten: " Diese Methode untersucht die aktuelle Ansicht und ihre Unteransichtshierarchie für das Textfeld, das derzeit der Ersthelfer ist. Wenn es eines findet, fordert es dieses Textfeld auf, als Ersthelfer zurückzutreten. Wenn der Parameter force auf gesetzt ist JA, das Textfeld wird nie gefragt; es muss zurücktreten. "
Gobot

1
Auf diese Weise wird meine Methode "didSelectRowAtIndexPath" nicht aufgerufen. irgendeine Lösung dafür?
uniruddh

127

Die UITapGestureRecognizer-Lösung funktioniert mit der Auswahl von Tabellenzellen, wenn Sie Folgendes festlegen:

gestureRecognizer.cancelsTouchesInView = NO;

1
Dies ermöglicht das Berühren der Zelle, aber die Geste wird auch erkannt. Vielleicht sollten wir diese Delegatenmethoden implementierenshouldReceiveTouch
onmyway133

61

Hier ist der beste Weg, dies zu tun. Mach das einfach

[self.view endEditing:YES];

oder

[[self.tableView superView] endEditing:YES];

Wo soll ich diesen Code ablegen? Entschuldigung, ich bin Anfänger. Und bitte geben Sie einen schnellen Code an.
John

54

Sie können dies auch über das Storyboard tun: Geben Sie hier die Bildbeschreibung ein


1
Was auch immer ich wähle: Beim Ziehen schließen, Interaktiv schließen Wenn ich die Tabellenzelle berühre, wird sie ausgewählt. Ich benutze Xcode 8, Swift 3. Bitte helfen Sie
John

22

Wie UITableViewbei einer Unterklasse von UIScrollViewbietet die Implementierung einer der folgenden Delegatenmethoden eine äußerst einfache und schnelle Lösung. Sie müssen nicht einmal einbeziehen, resignFirstResponderda die Ansichtshierarchie introspektiert und den aktuellen Antwortenden findet und ihn auffordert, seinen Antwortstatus zurückzuziehen.

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

Und denken Sie daran, UIScrollViewDelegatezur Header-Datei hinzuzufügen .


2
Dies kann durch diesen einen Liner erfolgen, wie von @Joe Masilotti hervorgehoben, wenn Sie auf iOS7 und höher abzielen: self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
atulkhatri

Was passiert, wenn Sie auf ein Textfeld am unteren Bildschirmrand tippen, das nach oben scrollen soll, um die Tastatur anzuzeigen? - Ihre Tastatur wird ausgeblendet.
Islam Q.

Swift 4 - self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.onDrag
RobLabs

13

Hören Sie zunächst scrollViewWillBeginDraggingin Ihrem UIViewControllernach, indem Sie das hinzufügenUIScrollViewDelegate :

In der .h-Datei:

@interface MyViewController : UIViewController <UIScrollViewDelegate> 

In der .m-Datei:

- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {

    [self dismissKeyboard];

}

Hören Sie dann auf andere Interaktionen:

- (void)setupKeyboardDismissTaps {

    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UISwipeGestureRecognizer *swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeDownGestureRecognizer.cancelsTouchesInView = NO;
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
    [self.tableView addGestureRecognizer:swipeDownGestureRecognizer];

    UISwipeGestureRecognizer *swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeLeftGestureRecognizer.cancelsTouchesInView = NO;
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.tableView addGestureRecognizer:swipeLeftGestureRecognizer];

    UISwipeGestureRecognizer *swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeRightGestureRecognizer.cancelsTouchesInView = NO;
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.tableView addGestureRecognizer:swipeRightGestureRecognizer];


    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

Dann implementieren Sie dismissKeyboard:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    [yourTextFieldPointer resignFirstResponder];

}

Und wenn Sie wie ich die Tastatur für ein UITextField in einer benutzerdefinierten Tabellenzelle schließen wollten:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    CustomCellClass *customCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    [customCell.textFieldInCell resignFirstResponder]; 

}

Hoffe das hilft jedem bei der Suche !!



8

Hier ist die schnelle Version für Ihr Codierungsvergnügen:

Es fügt eine Tippgestenerkennung hinzu und schließt dann die Tastatur. Für das TextField ist keine Steckdose erforderlich!

override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
}

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .Ended {
        view.endEditing(true)
    }
    sender.cancelsTouchesInView = false
}

1
Dies funktioniert sogar mit einer benutzerdefinierten tableViewCell! Ich habe so viel Zeit damit verbracht, dies herauszufinden. Ich danke dir sehr! Sie sind mein Held. youtu.be/EqWRaAF6_WY
Friedenstyp

8

Es gibt die Swift 3-Version, ohne das Abhören von Zellen zu blockieren.

In viewDidLoad()Methode:

let dismissKeyboardGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
dismissKeyboardGesture.cancelsTouchesInView = false
tableView.addGestureRecognizer(dismissKeyboardGesture)

Und hideKeyboardsieht so aus:

func hideKeyboard() {
    view.endEditing(true)
}

7

Ich habe es so gemacht:

Erstellen Sie in Ihrem TableViewController eine Methode, um den Ersthelfer zu deaktivieren (dies wäre zu diesem Zeitpunkt Ihre TextBox).

- (BOOL)findAndResignFirstResonder:(UIView *)stView {
    if (stView.isFirstResponder) {
        [stView resignFirstResponder];
        return YES;     
    }

    for (UIView *subView in stView.subviews) {
        if ([self findAndResignFirstResonder:subView]) {
            return YES;
        }
    }
    return NO;
}

In tableView:didSelectRowAtIndexPath:Aufruf der vorherigen Methode:

- (void)tableView:(UITableView *)tableView
                             didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    [self findAndResignFirstResonder: self.view];
    ...
}

Sie machen es falsch, wie Sie fragen. Sie setzen keine Schaltfläche auf die Ansicht. Sie

2
Dies funktioniert hervorragend, wenn Sie innerhalb einer Tabellenansichtszelle (und außerhalb eines UITextFields innerhalb dieser Tabellenansichtszelle) tippen. Wenn ich jedoch auf den Hintergrund der Tabellenansicht tippe (was oft ein leichter zu erreichendes Ziel ist - yay Fitts 'Gesetz!), Kein solches Glück. Dies wird zwar erwartet, da wir diesen Vorgang in tableView ausführen: didSelectRowAtIndexPath:. Wenn dies irgendwie angepasst werden kann, um mit dem Tippen auf eine andere Stelle in der Tabellenansicht zu funktionieren (das würde sonst keinen Tastaturfokus wollen), haben wir hier einen Gewinner!
Joe D'Andrea

Ich habe das gleiche Problem wie jdandrea. Das didSelectRowAtIndexPathwird nicht ausgelöst, wenn Sie auf die TableView selbst tippen.
Zekel

Wenn didSelectRowAtIndexPath nicht ausreicht, machen Sie dasselbe auch in touchBegan!
Amogh Talpallikar

5

Ich hatte eine UITableViewControllerund die Implementierung touchesBegan:withEvent:hat bei mir nicht funktioniert.

Folgendes hat funktioniert:

Schnell:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    view.endEditing(true)
}

Ziel c:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view endEditing:YES];
}

Gute Idee, ich mag es.
HotFudgeSunday

4
@interface DismissableUITableView : UITableView {
}
@end

@implementation DismissableUITableView

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

@end

Stellen Sie dann sicher, dass Sie in Ihrer Nib-Datei den Typ Ihrer UITableView auf DismissableUITableView setzen ..... vielleicht hätte ich mir einen besseren Namen für diese Klasse vorstellen können, aber Sie verstehen es.


4

Wenn Sie auf iOS7 abzielen, können Sie eine der folgenden Optionen verwenden:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Ersteres animiert die Tastatur außerhalb des Bildschirms, wenn die Tabellenansicht gescrollt wird, und letzteres versteckt die Tastatur wie die Standardnachrichten-App.

Beachten Sie, dass diese von sind UIScrollView, die von UITableViewerben.


nett. Ich schaffte es, es irgendwie zu brechen, indem ich von oben nach oben wischte, bis sich die Tastatur nach unten bewegte, dann wieder nach oben wischte, bis sich die Tastatur ein wenig nach oben bewegte, und dann losließ. Die Bildlaufansicht springt nicht wie gewünscht nach oben zurück.
Sam

3

Versuche dies:

viewDidLoad(){

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

    tableView.addGestureRecognizer(tap)

}
//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {

    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)

}

2

UITableView ist eine Unterklasse von UIScrollView.

So wie ich es gemacht habe, habe ich auf ein Scroll-Ereignis des Benutzers gewartet und dann resignFirstResponder. Hier ist die UIScrollViewDelegate-Methode, die Sie in Ihren Code implementieren können.

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

Wenn ich mich solchen Problemen nähere, habe ich festgestellt, dass der beste Weg darin besteht, die Delegatenprotokolle für jedes Objekt und die der übergeordneten Klassen (in diesem Fall UITableViewDelegate, UIScrollViewDelegate) zu untersuchen. Die Anzahl der Ereignisse, die NS-Objekte auslösen, ist ziemlich groß und umfassend Es ist auch einfacher, ein Protokoll zu implementieren, als irgendetwas zu unterklassifizieren.


2

Ich hatte das gleiche Problem und hier ist meine Lösung, es funktioniert perfekt für mich:

In der Ansicht oder Ansichtssteuerung, die Sie implementiert haben <UITextFieldDelegate>

(In meinem Fall habe ich einen Brauch UITableViewCell namens TextFieldCell),

Deklarieren Sie das UITapGestureRecognizerals Eigenschaft:

@interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
    UITextField *theTextField;
    UITapGestureRecognizer *gestureRecognizer;
}
@property (nonatomic,retain) UITextField *theTextField;
@property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer; 

Und initialisieren Sie es in Ihrer Ansicht / Ihrem Controller:

self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)];

- (void)textFieldDidBeginEditing:(UITextField *)textFieldVerwenden Sie superViewin der Methode, um zu Ihrer tableView zu gelangen und Folgendes aufzurufen addGestureRecognizer:

[self.superview.superview addGestureRecognizer:gestureRecognizer];

Und in der - (void)textFieldDidEndEditing:(UITextField *)textFieldentfernen Sie einfach die Gestenerkennung:

[self.superview.superview removeGestureRecognizer:gestureRecognizer];

Ich hoffe es hilft.


Das hat es für mich getan. Danke hac.jack
gilsaints88

2

Ich wollte, dass meine Zelle die Tastatur öffnet, wenn ein Teil der Zelle ausgewählt wurde, und sie schließt, wenn Sie irgendwo außerhalb der Zelle geklickt haben. So öffnen Sie die Tastatur:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    if (selected)
    {
        [self.textField becomeFirstResponder];
    }
}

(HINWEIS: Ich habe die Zelle in Unterklassen unterteilt, aber Sie können dies problemlos mit der tableView:didSelectRowAtIndexPath:Delegate-Methode von erreichenUITableView )

Dies bedeutete, dass bei den Top-Lösungen, wenn Sie zweimal auf die Zelle klickten, die Tastatur zitterte, als erstens der Gestenerkenner versuchte, die Tastatur zu schließen, und zweitens die Zelle erneut ausgewählt und versucht wurde, die Tastatur zu öffnen.

Die Lösung besteht darin, zu überprüfen, ob der Klick in der aktuell ausgewählten Zelle aufgetreten ist:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //gesture recognizer to close the keyboard when user taps away
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard:)];
    tap.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tap];
}

-(void)dismissKeyboard:(UIGestureRecognizer*)tapGestureRecognizer
{
    if (!CGRectContainsPoint([self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]].frame, [tapGestureRecognizer locationInView:self.tableView]))
    {
        [self.view endEditing:YES];
    }
}

2

Ich habe eine Lösung gefunden, die großartig funktioniert.

Wird benötigt, um UIGestureRecognizerDelegate und die Methode zu verwenden - gestureRecognizer: shouldReceiveTouch: .

Fügen Sie die Gestenerkennung wie folgt zur TableView hinzu:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.delegate = self;
[self.suggestedTableView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

Implementieren Sie dann die delegierte Methode shouldReceiveTouch , um Berührungen abzulehnen, die in der UITableViewCell-Klasse ausgeführt werden. Die hideKeyboard- Methode wird nur aufgerufen, wenn die Berührung außerhalb der UITableViewCell-Klasse ausgeführt wurde.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if([touch.view isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCell
    if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
    if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    return YES; // handle the touch
}

- (void) hideKeyboard{
    [textField resignFirstResponder];
}

2

UITableViewhat eine praktische backgroundViewEigenschaft, mit der ich dieses Verhalten erreicht habe, ohne die Zellenauswahl zu beeinträchtigen, wie unten in Swift gezeigt:

let tableBackTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tableView.backgroundView = UIView()
tableView.backgroundView?.addGestureRecognizer(tableBackTapRecognizer)


1

Die einfache Verwendung eines UITapGestureRecognizers cancelsTouchesInView = NObedeutet, dass durch Tippen auf Zellen und UITextViews auch das Ausblenden ausgelöst wird. Dies ist schlecht, wenn Sie mehrere UITextViews haben und auf die nächste tippen. Die Tastatur beginnt sich auszublenden und dann wird die nächste Textansicht zum ersten Antwortenden und die Tastatur wird wieder sichtbar. Um dies zu vermeiden, überprüfen Sie die Position des Tippen und verbergen Sie die Tastatur nur, wenn sich das Tippen nicht in einer Zelle befindet:

// init
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTableView:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:tapRecognizer];


// Hide on tap
- (void)didTapTableView:(UITapGestureRecognizer *)tap
{
    CGPoint point = [tap locationInView:tap.view];
    [self.view endEditing:!CGRectContainsPoint([self.tableView rectForRowAtIndexPath:[self.tableView indexPathForRowAtPoint:point]], point)];
}

Um scrollViewWillBeginDragging:ausgelöst zu werden, muss die scrollEnabledEigenschaft von tableView seinYES

// Hide on scroll
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

Perfekt für mich. Es wurde eine Texbox zur Tabellenansichtszelle hinzugefügt. wenn ich außerhalb der Tastatur berühre, entlassen
Nicola

0

Warum möchten Sie eine Tabelle voller Textfelder erstellen? Sie sollten für jede Zeile, die die Textfelder enthält, eine Detailansicht verwenden. Stellen Sie beim Verschieben Ihrer Detailansicht sicher, dass Sie "[myTextField werden zum ersten Antwortgeber]" aufrufen, damit der Benutzer mit nur einem Klick von der Tabellenliste entfernt mit der Bearbeitung beginnen kann.


Apples Kontakte-App macht genau das. Ich würde nicht sagen, dass es per se voller Textfelder ist, aber es nutzt sie effektiv.
Joe D'Andrea

2
Das Inline-Bearbeiten von Text in einer Tabellenansicht ist viel schneller und intuitiver als das Verschieben von Detailansichten für jedes Textfeld, das der Benutzer bearbeiten möchte. Fragen Sie einfach das nächstgelegene HTML-Formular oder die Textfelder in den Fenstern der iPhone-Einstellungen oder in der Kontakte-App oder etc etc etc ... es ist wirklich schade, dass Apple dies nicht zu einem Standardzelltyp gemacht hat, aber es gibt viele Informationen im Internet darüber, wie dies erreicht werden kann.
Glenc

0

Wenn Sie bereit sind, Ihre Tabellenansicht in eine Unterklasse (ugh!) Zu unterteilen, könnte Folgendes funktionieren:

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

   BOOL backgroundTouched = YES;

   for (UITouch *touch in touches) {
      CGPoint location = [touch locationInView:self];
      for (UITableViewCell *cell in self.visibleCells) {
         if (CGRectContainsPoint(cell.frame, location)) {
            backgroundTouched = NO;
            break;
         }
      }
   }

   if (backgroundTouched) {
      for (UITableViewCell *cell in self.visibleCells) {
         // This presumes the first subview is the text field you want to resign.
         [[cell.contentView.subviews objectAtIndex:0] resignFirstResponder];
      }
   }

   [super touchesBegan:touches withEvent:event];
}

0

Wenn Sie die Tastatur schließen möchten, während die Eingabetaste gedrückt wird, können Sie einfach den folgenden Code in textField hinzufügen, falls die Methode zurückgegeben wird:

- (BOOL)textFieldShouldReturn:(UITextField *)atextField
{
   [textField resignFirstresponder];
}

Einige Textfelder haben möglicherweise eine Auswahlansicht oder eine andere als Unteransicht. In diesem Fall funktioniert die obige Methode nicht. In diesem Fall müssen wir die UITapGestureRecognizer-Klasse verwenden, dh fügen Sie der viewDidLoad-Methode das folgende Codeausschnitt hinzu:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard)];

    [self.view addGestureRecognizer:tap];

Fügen Sie nun einfach den Resign-Responder zur Auswahlmethode hinzu, dh:

-(void)dismissKeyboard 
{
    [textField resignFirstResponder];
}

Hoffe es hilft, danke :)


0

Viele interessante Antworten. Ich möchte verschiedene Ansätze in die Lösung einbauen, die meiner Meinung nach am besten zu einem UITableView-Szenario passt (es ist das, das ich normalerweise verwende): Normalerweise möchten wir die Tastatur in zwei Szenarien ausblenden: beim Tippen außerhalb der Text-UI-Elemente, oder beim Scrollen nach unten / oben in der UITableView. Das erste Szenario können wir einfach über einen TapGestureRecognizer und das zweite über die UIScrollViewDelegate scrollViewWillBeginDragging: -Methode hinzufügen. Erste Aufgabe, die Methode zum Ausblenden der Tastatur:

   /**
     *  Shortcut for resigning all responders and pull-back the keyboard
     */
    -(void)hideKeyboard
    {
        //this convenience method on UITableView sends a nested message to all subviews, and they resign responders if they have hold of the keyboard
        [self.tableView endEditing:YES];

    }

Diese Methode gibt alle textField-Benutzeroberflächen der Unteransichten innerhalb der UITableView-Ansichtshierarchie zurück. Daher ist es praktischer, als jedes einzelne Element unabhängig zurückzulegen.

Als nächstes kümmern wir uns um die Entlassung über eine externe Tap-Geste mit:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setupKeyboardDismissGestures];

}

- (void)setupKeyboardDismissGestures
{

//    Example for a swipe gesture recognizer. it was not set-up since we use scrollViewDelegate for dissmin-on-swiping, but it could be useful to keep in mind for views that do not inherit from UIScrollView
//    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
//    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
//    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
//    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
    //this prevents the gestureRecognizer to override other Taps, such as Cell Selection
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

Wenn Sie tapGestureRecognizer.cancelsTouchesInView auf NO setzen, wird verhindert, dass der gestureRecognizer das normale Innenleben von UITableView überschreibt (z. B. um die Zellenauswahl nicht zu beeinträchtigen).

Um das Ausblenden der Tastatur beim Scrollen nach oben / unten in der UITableView zu handhaben, müssen wir die UIScrollViewDelegate-Protokoll-Methode scrollViewWillBeginDragging: wie folgt implementieren:

.h Datei

@interface MyViewController : UIViewController <UIScrollViewDelegate>

.m Datei

#pragma mark - UIScrollViewDelegate

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self hideKeyboard];
}

Ich hoffe, es hilft! =)


0

Hier ist, wie ich endlich funktioniert habe. Ich habe Vorschläge und Codes aus verschiedenen Antworten kombiniert. Funktionen: Schließen der Tastatur, Verschieben von Textfeldern über die Tastatur beim Bearbeiten und Einstellen des Tastaturrückgabetyps "Weiter" und "Fertig". ERSETZEN Sie "..." durch weitere Felder

static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;

@interface ViewController () <UITextFieldDelegate>
 @property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
  .....// some other text fields
 @property (weak, nonatomic) IBOutlet UITextField *emailTXT;
@end

@implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(tapScreen:)];// outside textfields

[self.view addGestureRecognizer:tapGesture];

// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];

// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];

// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self     selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self      selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}

// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
  if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
  ...
  if([self.emailTXT isFirstResponder])[self.emailTXT  resignFirstResponder];

  }
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
   if(textField.returnKeyType==UIReturnKeyNext) {
     // find the text field with next tag
     UIView *next = [[textField superview] viewWithTag:textField.tag+1];
     [next becomeFirstResponder];
   } else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
    [textField resignFirstResponder];
 }
return YES;
}

// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
   CGRect viewFrame = self.view.frame;
   CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
   CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
   CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//

   CGFloat keyboardHeight = keyboardSize.height;

   BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
  if (isTextFieldHidden) {
    animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
    viewFrame.origin.y -= animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
  return YES;
}

-(void) restoreViewFrameOrigionYToZero{
  CGRect viewFrame = self.view.frame;
  if (viewFrame.origin.y != 0) {
    viewFrame.origin.y = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
}

-(void)keyboardDidShow:(NSNotification*)aNotification{
   NSDictionary* info = [aNotification userInfo];
   keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
 }

-(void)keyboardDidHide:(NSNotification*)aNotification{
   [self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its  zero origin
}
@end

0

Die Antwort von @ mixca ist sehr nützlich, aber was ist, wenn ich etwas anderes als UITextField habe? Ich denke, der beste Weg, um damit umzugehen, indem alle Unteransichten der Hauptansicht mit rekursiver Funktion durchsucht werden, siehe Beispiel unten

- (BOOL)findAndResignFirstResponder {
if (self.isFirstResponder) {
    [self resignFirstResponder];
    return YES;
}

    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder]) {
            return YES;
        }
    }
    return NO;
}

Außerdem können Sie diese Methode in Ihre Utility-Klasse einfügen und eine Tippgeste wie die Antwort von @ mixca verwenden.


0

Swift 4 / 4.2 / 5

Sie können die Tastatur auch schließen, wenn Sie auf eine Zelle tippen - bevor Sie etwas anderes tun.

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    view.endEditing(true)
    // Do something here
    }

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.