Comment fermer le clavier pour UITextView avec la touche retour?


382

Dans la bibliothèque d'IB, l'introduction nous indique que lorsque la returntouche est enfoncée, le clavier de UITextViewdisparaîtra. Mais en réalité, la returnclé ne peut agir que comme «\ n».

Je peux ajouter un bouton et utiliser [txtView resignFirstResponder]pour masquer le clavier.

Mais existe-t-il un moyen d'ajouter l'action pour la returntouche du clavier afin que je n'aie pas besoin d'ajouter UIButton?


Suivez les instructions sur cet article de blog: iphonedevelopertips.com/cocoa/…
ManojN

Réponses:


354

UITextViewn'a aucune méthode qui sera appelée lorsque l'utilisateur appuiera sur la touche retour. Si vous souhaitez que l'utilisateur ne puisse ajouter qu'une seule ligne de texte, utilisez a UITextField. Frapper le retour et masquer le clavier pour un UITextViewne suit pas les directives d'interface.

Même alors, si vous voulez le faire, implémentez la textView:shouldChangeTextInRange:replacementText:méthode de UITextViewDelegateet dans cette vérification si le texte de remplacement est \n, cachez le clavier.

Il pourrait y avoir d'autres moyens mais je n'en connais aucun.


1
Merci et la méthode fonctionne bien. La raison d'utiliser UITextView est qu'il peut contenir du texte sur plusieurs lignes. Et maintenant, je l'utilise comme boîte de message.
Chilly Zhong

28
Il est assez facile de changer la clé de retour en "terminé" en utilisant soit [textField setReturnKeyType: UIReturnKeyDone];ou en utilisant le générateur d'interface
Casebash

9
D'accord, je comprends maintenant que la façon dont Apple termine avec un champ de texte multiligne est d'ajouter terminé à la barre de menus
Casebash

8
Ce n'est pas un bon moyen de résoudre ce problème car vous limitez l'utilisateur à utiliser Entrée pour sortir du clavier. La meilleure façon est probablement d'ajouter un bouton qui exécute la méthode resignFirstResponder.
Ele

5
@Casebash. Il semble que définir la clé de retour sur "terminé" ne résout pas le problème dans Xcode 6.4, Swift 2.0. J'ai défini la clé en utilisant IB.
MB_iOSDeveloper

505

Je pensais que je publierais l'extrait ici à la place:

Assurez-vous de déclarer la prise en charge du UITextViewDelegateprotocole.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    if([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}

Mise à jour Swift 4.0:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

75
Le problème est que ce n'est pas vraiment un moyen de détecter que l'utilisateur a appuyé sur la touche de retour . L'utilisateur peut coller un caractère de retour dans le champ de texte et vous obtiendrez le même message de délégué. Fondamentalement, vous abusez de la vue texte. La façon de fermer le clavier est (1) de ne pas le faire du tout (comme lors de la composition d'un message dans l'application Mail) ou (2) d'avoir un bouton Terminé ailleurs dans l'interface (comme dans l'application Notes). Vous pouvez par exemple attacher un tel bouton comme vue accessoire au clavier.
mat

@ Sam V cet extrait était un homme cool. ça marche pour moi. merci un homme de tonne. Existe-t-il un extrait de code pour la dissémination du clavier numérique. ce qui concerne shishir
Shishir.bobby

Magnifique. Juste un rappel que dans certaines situations, pour se débarrasser du clavier, essayez le long des lignes ... [self.view endEditing: YES];
Fattie

@Vojto, fonctionne très bien sur iPad. Vous n'avez probablement pas défini le délégué.
Vincent

4
Le problème est que le clavier peut masquer une partie de l'interface utilisée pour ignorer. Il est vraiment absurde que IOS ne dispose pas d'un bouton sur chaque clavier dédié pour ignorer le clavier afin que l'utilisateur puisse le faire s'il le souhaite.
Sani Elfishawy

80

Je sais que cela a déjà été répondu, mais je n'aime pas vraiment utiliser le littéral de chaîne pour la nouvelle ligne, alors voici ce que j'ai fait.

- (BOOL)textView:(UITextView *)txtView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if( [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound ) {
        return YES;
    }

    [txtView resignFirstResponder];
    return NO;
}

Mise à jour Swift 4.0:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text as NSString).rangeOfCharacter(from: CharacterSet.newlines).location == NSNotFound {
    return true
}
txtView.resignFirstResponder()
return false
}

6
Je pourrais le modifier comme ceci: NSRange resultRange = [text rangeOfCharacterFromSet: [NSCharacterSet newlineCharacterSet] options: NSBackwardsSearch]; Parce que c'est un hack de toute façon, il semble que vérifier la fin de la chaîne pour un retour soit un itinéraire plus sûr.
maxpower

@maxpower Très bon commentaire. En outre, il est préférable de vérifier le texte remplacé, par exemple NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text].
Rudolf Adamkovič

Imaginez un utilisateur collant du texte copié ailleurs contenant une nouvelle ligne. Ils seraient probablement confus lorsque, au lieu d'ajouter le texte, l'application rejette simplement le clavier.
Nikolai Ruhe du

44

Je sais que cela a été répondu à de nombreuses reprises, mais voici mes deux cents à la question.

J'ai trouvé les réponses de samvermette et ribeto très utiles, ainsi que le commentaire de maxpower dans la réponse de ribeto . Mais il y a un problème avec ces approches. Le problème que Matt mentionne dans la réponse de la samvermette et c'est que si l'utilisateur veut coller quelque chose avec un saut de ligne à l'intérieur, le clavier se cacherait sans rien coller.

Mon approche consiste donc à mélanger les trois solutions mentionnées ci-dessus et à ne vérifier que si la chaîne entrée est une nouvelle ligne lorsque la longueur de la chaîne est 1, nous nous assurons donc que l'utilisateur tape au lieu de coller.

Voici ce que j'ai fait:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];
    if ([text length] == 1 && resultRange.location != NSNotFound) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}

Il s'agit d'une meilleure solution à ce problème. La réponse de samvermette ne tient pas compte de la situation où l'utilisateur souhaite coller un texte.
marcopaivaf

36

Une manière plus élégante consiste à fermer le clavier lorsque l'utilisateur appuie quelque part en dehors du cadre du clavier.

Tout d'abord, définissez la vue de votre ViewController sur la classe "UIControl" dans l'inspecteur d'identité dans UIBuilder. Faites glisser la vue dans le fichier d'en-tête de ViewController et liez-la en tant qu'action avec l'événement comme Touch Up Inside, par exemple:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

Dans le fichier principal de ViewController, ViewController.m:

-(IBAction)dismissKeyboardOnTap:(id)sender
    {
         [[self view] endEditing:YES];
    }

Vous pouvez exiger un double tapotement ou une longue pression en utilisant des techniques similaires. Vous devrez peut-être définir votre ViewController pour qu'il soit un UITextViewDelegate et connecter le TextView au ViewController. Cette méthode fonctionne pour UITextView et UITextField.

Source: Ranch Big Nerd

EDIT: Je voudrais également ajouter que si vous utilisez un UIScrollView, la technique ci-dessus peut ne pas fonctionner aussi facilement via Interface Builder. Dans ce cas, vous pouvez utiliser un UIGestureRecognizer et appeler à la place la méthode [[self view] endEditing: YES]. Un exemple serait:

-(void)ViewDidLoad{
    ....
    UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] 
        initWithTarget:self action:@selector(tap:)];
    [self.view addGestureRecognizer: tapRec];
    ....
}

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
}

Lorsque l'utilisateur touche en dehors du clavier et ne touche pas d'espace d'entrée, le clavier se ferme.


1
J'aime l'idée avec GestureRecognizermais l'énorme problème est que tous les boutons ou contrôles de la vue ne sont plus cliquables.
expert

35

Ajoutez cette méthode dans votre contrôleur de vue.

Rapide :

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

Cette méthode peut également vous être utile:

/**
Dismiss keyboard when tapped outside the keyboard or textView

:param: touches the touches
:param: event   the related event
*/
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if touch.phase == UITouchPhase.Began {
            textField?.resignFirstResponder()
        }
    }
}

2
N'oubliez pas de confirmer le protocole UITextViewDelegate :)
swiftBoy

Je ne pense pas que ce soit une bonne idée de remplacer les touchesBegan et de ne pas appeler super.touchesBegan(touches:withEvent:).
TGO

Pour exprimer la nature symétrique de ce code, vous devez écrire else { return true }.
signification compte

@ signification-importe pas du tout
Alexander Volkov

@AlexanderVolkov Vous n'êtes pas d'accord pour dire que c'est une situation symétrique, vous ne savez pas ce que je veux dire, vous ne croyez pas à la valeur d'un code sémantiquement correct, ou, ...?
signification est importante

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

yourtextView.delegate=self;

Ajoutez également UITextViewDelegate

N'oubliez pas de confirmer le protocole

SI vous n'avez pas ajouté, if([text isEqualToString:@"\n"])vous ne pouvez pas modifier


2
-1 Ceci est juste une version plus pauvre de la réponse de samvermette. Vous avez manqué de revenir NOsi le texte est égal à @"\n".
devios1

17

Il existe une autre solution lors de l'utilisation avec uitextview, vous pouvez ajouter la barre d'outils en tant que InputAccessoryView dans "textViewShouldBeginEditing", et à partir du bouton terminé de cette barre d'outils, vous pouvez fermer le clavier, le code pour cela est le suivant:

In viewDidLoad

toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)]; //toolbar is uitoolbar object
toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(btnClickedDone:)];
[toolBar setItems:[NSArray arrayWithObject:btnDone]];

Dans la méthode textviewdelegate

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
     [textView setInputAccessoryView:toolBar];
     return YES;
}

En action du bouton Terminé qui se trouve dans la barre d'outils est le suivant:

-(IBAction)btnClickedDone:(id)sender
{
    [self.view endEditing:YES];
}

17

J'ai trouvé que la réponse de josebama était la réponse la plus complète et la plus claire disponible dans ce fil.

Voici la syntaxe Swift 4 pour cela:

func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool {
    let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards)
    if text.count == 1 && resultRange != nil {
        textView.resignFirstResponder()
        // Do any additional stuff here
        return false
    }
    return true
}

L' resultRangeobjectif est de tester si le texte ne contient que des sauts de ligne qui évitent le code dur "\ n".
Qinghua

6

rapide

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
    }
    return true
}

et configurer


D'où vient cette capture d'écran?
Sam

6

Utilisation du contrôleur de navigation pour héberger une barre pour fermer le clavier:

dans le fichier .h:

UIBarButtonItem* dismissKeyboardButton;

dans le fichier .m:

- (void)viewDidLoad {
    dismissKeyboardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard)];
}

-(void)textViewDidBeginEditing:(UITextView *)textView {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)dismissKeyboard {
    [self.textField resignFirstResponder];
    [self.textView resignFirstResponder];
    //or replace this with your regular right button
    self.navigationItem.rightBarButtonItem = nil;
}

5

Tout comme un commentaire mat à samvermette, je n'aime pas non plus l'idée de détecter "\ n". La touche "retour" est là pour une raison dans UITextView, c'est d'aller à la ligne suivante bien sûr.

La meilleure solution à mon avis est d'imiter l'application de message iPhone - qui consiste à ajouter une barre d'outils (et un bouton) sur le clavier.

J'ai reçu le code du blog suivant:

http://www.iosdevnotes.com/2011/02/iphone-keyboard-toolbar/

Pas:

-Ajouter la barre d'outils à votre fichier XIB - définissez la hauteur sur 460

-Ajouter un élément du bouton de la barre d'outils (s'il n'est pas déjà ajouté). Si vous devez l'aligner à droite, ajoutez également l'élément de bouton de barre flexible à XIB et déplacez l'élément de bouton de barre d'outils

-Créer une action qui relie votre élément de bouton à resignFirstResponder comme suit:

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

-Alors:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height - 260.0;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}

Hors sujet. Bien que votre solution soit élégante, elle ne répond pas à la question d'origine: "Comment supprimer le clavier pour UITextView avec la touche retour?". Il existe des situations où UITextView est utilisé pour simuler un habillage de mot UITextField, et non pour entrer plusieurs lignes.
SwiftArchitect

2
Bien qu'il soit hors sujet, il est très utile. Je veux également qu'un UITextView soit entré avec plusieurs lignes et que je rejette le clavier quand je le veux.
Yeung

5

Je viens de résoudre ce problème d'une manière différente.

  • Créez un bouton qui sera placé en arrière-plan
  • Dans l'inspecteur d'attributs, changez le type de bouton en personnalisé et rend le bouton transparent.
  • Développez le bouton pour couvrir toute la vue et assurez-vous qu'il se trouve derrière tous les autres objets. Pour ce faire, il vous suffit de faire glisser le bouton en haut de la liste dans la vue
  • Faites glisser le bouton vers le viewController.hfichier et créez une action (Événement envoyé: Retouche à l'intérieur) comme:

    (IBAction)ExitKeyboard:(id)sender;
  • Dans ViewController.m devrait ressembler à:

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
  • Exécutez l'application et lorsque vous cliquez en dehors de TextView, le clavier disparaît

Vous devez également ajouter: - (void) textViewDidEndEditing: (UITextView *) textView {[self.TextView resignFirstResponder]; }
samouray

5

Ajouter un observateur dans viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(textViewKeyPressed:) name: UITextViewTextDidChangeNotification object: nil];

puis utilisez le sélecteur pour vérifier "\ n"

-(void) textViewKeyPressed: (NSNotification*) notification {

  if ([[[notification object] text] hasSuffix:@"\n"])
  {
    [[notification object] resignFirstResponder];
  }
}

Il utilise "\ n" et ne vérifie pas spécifiquement une clé de retour, mais je pense que c'est OK.

MISE À JOUR

Voir la réponse de ribto ci-dessous qui utilise [NSCharacterSet newlineCharacterSet]à la place de\n


Err, il utilise \net la clé de retour est détectée en fonction de \nsorte qu'il vérifie la clé de retour. La seule différence est que vous utilisez des notifications plutôt que d'utiliser les textViewDelegates.
GoodSp33d

Maintenant, je pense que vérifier [NSCharacterSet newlineCharacterSet]plutôt que \ n pourrait être une meilleure façon de procéder.
ToddB

5

Code rapide

Implémentez UITextViewDelegate dans votre classe / View comme ceci:

class MyClass: UITextViewDelegate  { ...

définissez le délégué textView sur self

myTextView.delegate = self

Et puis implémentez les éléments suivants:

  func textViewDidChange(_ textView: UITextView) {
    if textView.text.characters.count >= 1 {

        if let lastChar = textView.text.characters.last {

            if(lastChar == "\n"){

              textView.text = textView.text.substring(to: textView.text.index(before: textView.text.endIndex))
              textView.resignFirstResponder()
            }
        }
    }
}

EDIT J'ai mis à jour le code car ce n'est jamais une bonne idée de changer l'entrée utilisateur dans un champ de texte pour une solution de contournement et de ne pas réinitialiser l'état une fois le code de piratage terminé.


4

Essaye ça :

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    if ([text isEqualToString:@"\n"]) {
        [self.view endEditing:YES];
    }

    return YES;

}

4

// Vous pouvez utiliser ceci ...

Étape 1. La première étape consiste à vous assurer que vous déclarez la prise en charge du UITextViewDelegateprotocole. Cela se fait dans votre fichier d'en-tête, comme exemple voici l'en-tête appelé

EditorController.h:

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

Étape 2. Ensuite, vous devrez enregistrer le contrôleur en tant que délégué de l'UITextView. En UITextViewreprenant l'exemple ci-dessus, voici comment j'ai initialisé le avec en EditorControllertant que délégué…

- (id) init {
    if (self = [super init]) {
        // define the area and location for the UITextView
        CGRect tfFrame = CGRectMake(10, 10, 300, 100);
        messageTextView = [[UITextView alloc] initWithFrame:tfFrame];
        // make sure that it is editable
        messageTextView.editable = YES;

        // add the controller as the delegate
        messageTextView.delegate = self;
    }

Étape 3. Et maintenant, la dernière pièce du puzzle consiste à agir en réponse au shouldCahngeTextInRangemessage comme suit:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 
  replacementText:(NSString *)text
{
    // Any new character added is passed in as the "text" parameter
    if ([text isEqualToString:@"\n"]) {
        // Be sure to test for equality using the "isEqualToString" message
        [textView resignFirstResponder];

        // Return FALSE so that the final '\n' character doesn't get added
        return FALSE;
    }
    // For any other character return TRUE so that the text gets added to the view
    return TRUE;
}

3

Vous pouvez également masquer le clavier lorsque vous touchez dans l'écran d'affichage:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch * touch = [touches anyObject];
     if(touch.phase == UITouchPhaseBegan) {
        [txtDetail resignFirstResponder];
      }
 }

À mon humble avis, c'est une très bonne approche, bien meilleure qu'avec un bouton qui couvre toute la vue.
WebOrCode

3

Réponse rapide:

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
    view.addGestureRecognizer(tapGestureReconizer)
}

func tap(sender: UITapGestureRecognizer) {
    view.endEditing(true)
}

3

J'ai utilisé ce code pour changer de répondeur.

 - (BOOL)textView:(UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
    {
        if ([text isEqualToString:@"\n"]) {
            //[textView resignFirstResponder];
            //return YES;
            NSInteger nextTag = textView.tag + 1;
            // Try to find next responder
            UIResponder* nextResponder = [self.view viewWithTag:nextTag];
            if (nextResponder) {
                // Found next responder, so set it.
                [nextResponder becomeFirstResponder];
            } else {
                // Not found, so remove keyboard.
                [textView resignFirstResponder];
            }
            return NO; 


            return NO;
        }
        return YES;

    }

pourquoi ne pas utiliser [self.view endEditing: YES]; une fois que??
ajay_nasa

3

La question demande comment le faire avec la touche retour mais je pense que cela pourrait aider quelqu'un avec l'intention de simplement faire disparaître le clavier lors de l'utilisation de UITextView:

private func addToolBarForTextView() {
    let textViewToolbar: UIToolbar = UIToolbar()
    textViewToolbar.barStyle = .default
    textViewToolbar.items = [
        UIBarButtonItem(title: "Cancel", style: .done,
                  target: self, action: #selector(cancelInput)),
        UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
                  target: self, action: nil),
        UIBarButtonItem(title: "Post Reply", style: .done,
                  target: self, action: #selector(doneInput))
    ]
    textViewToolbar.sizeToFit()
    yourTextView.inputAccessoryView = textViewToolbar
}

@objc func cancelInput() { print("cancel") }
@objc func doneInput() { print("done") }

override func viewDidLoad() {
    super.viewDidLoad()
    addToolBarForTextView()
}

Appelez addToolBarForTextView () dans viewDidLoad ou une autre méthode de cycle de vie.

Il semble que c'était la solution parfaite pour moi.

À votre santé,

Murat


1
Pour 2019, copiez et collez maintenant, aucune erreur de syntaxe et dénomination actuelle
Fattie

1
de loin la meilleure réponse ici. Je viens de corriger l'erreur de syntaxe simple, bien sûr, éditez comme vous le souhaitez. Merci!
Fattie

2

D'accord. Tout le monde a donné des réponses avec des astuces mais je pense que la bonne façon d'y parvenir est de

Connexion de l'action suivante à l' événement " Did End On Exit " dans Interface Builder. (cliquez avec le bouton droit de la souris TextFieldet faites glisser le curseur de la souris sur " Fin de la sortie " jusqu'à la méthode suivante.

-(IBAction)hideTheKeyboard:(id)sender
{
    [self.view endEditing:TRUE];
}

6
-1 La question concerne UITextView et non UITextField mon ami
Yogi

2
la plupart de ces réponses sont ici avec des votes car elles conviennent à différents scénarios de différents développeurs.
carbonr

Si vous utilisez un UITextField, c'est la façon de le faire. BTW, vous devez utiliser OUI / NON pour les booléens Objective-C, pas VRAI / FAUX.
Jon Shier

1
@jshier: TRUE / FALSE est OK aussi
Yogi

2

Similaire à d'autres réponses utilisant la UITextViewDelegatemais une interface rapide plus récente isNewlineserait:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let character = text.first, character.isNewline {
        textView.resignFirstResponder()
        return false
    }
    return true
}

1
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  replacementText:(NSString *)text
{
    if (range.length==0) {
        if ([text isEqualToString:@"\n"]) {
            [txtView resignFirstResponder];
            if(textView.returnKeyType== UIReturnKeyGo){

                [self PreviewLatter];
                return NO;
            }
            return NO;
        }
    }   return YES;
}

1
+ (void)addDoneButtonToControl:(id)txtFieldOrTextView
{
    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
        txtFieldOrTextView = (UITextField *)txtFieldOrTextView;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
        txtFieldOrTextView = (UITextView *)txtFieldOrTextView;
    }

    UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,
                                                                          0,
                                                                          [Global returnDeviceWidth],
                                                                          50)];
    numberToolbar.barStyle = UIBarStyleDefault;


    UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_return"]
                                                                style:UIBarButtonItemStyleBordered
                                                               target:txtFieldOrTextView
                                                               action:@selector(resignFirstResponder)];

    numberToolbar.items = [NSArray arrayWithObjects:btnDone,nil];
    [numberToolbar sizeToFit];

    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
         ((UITextField *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
         ((UITextView *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
}

0

Je sais que ce n'est pas la réponse exacte à cette question, mais j'ai trouvé ce fil après avoir cherché sur Internet une réponse. Je suppose que les autres partagent ce sentiment.

C'est mon écart de l'UITapGestureRecognizer que je trouve fiable et facile à utiliser - il suffit de définir le délégué du TextView au ViewController.

Au lieu de ViewDidLoad, j'ajoute UITapGestureRecognizer lorsque TextView devient actif pour l'édition:

-(void)textViewDidBeginEditing:(UITextView *)textView{
    _tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];

    [self.view addGestureRecognizer: _tapRec];
    NSLog(@"TextView Did begin");
}

Lorsque je tape en dehors de TextView, la vue met fin au mode d'édition et UITapGestureRecognizer se supprime pour que je puisse continuer à interagir avec les autres contrôles de la vue.

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
    [self.view removeGestureRecognizer:tapRec];
    NSLog(@"Tap recognized, tapRec getting removed");
}

J'espère que ça aide. Cela semble si évident, mais je n'ai jamais vu cette solution nulle part sur le Web - est-ce que je fais quelque chose de mal?


0

N'oubliez pas de définir le délégué pour le textView - sinon resignfirst responder ne fonctionnera pas.


0

Essaye ça .

NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];

0

Pour Xcode 6.4., Swift 1.2. :

   override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
    {
        super.touchesBegan(touches, withEvent: event)
        if let touch = touches.first as? UITouch
        {
            self.meaningTextview.resignFirstResponder()
        }
    }

0

Vous devez ajouter UIToolbaren haut UITextView pour faciliter plutôt que d'utilisershouldChangeTextIn

Dans Swift 4

let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        toolbar.barStyle = .default
        toolbar.items = [
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
            UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneAction))
        ]
        textView.inputAccessoryView = toolbar
@objc func doneAction(){
 self.textView.resignFirstResponder()
}

De loin la meilleure solution. Notez qu'au lieu de définir le cadre, utilisez simplementtoolbar.sizeToFit()
Fattie
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.