web-dev-qa-db-fra.com

Masquer le curseur d'un UITextField

J'utilise un UITextField avec un UIPickerView pour son inputView, de sorte que lorsque l'utilisateur appuie sur le champ de texte, un sélecteur est appelé pour lui permettre de sélectionner une option.

Presque tout fonctionne, mais j'ai un problème: le curseur clignote quand même dans le champ de texte lorsqu'il est actif, ce qui est laid et inapproprié, car l'utilisateur n'est pas censé taper dans le champ et n'est pas présenté avec un clavier. Je sais que je pourrais résoudre ce problème en définissant editing sur NO dans le champ de texte et son suivi, ou en le remplaçant par un bouton de style personnalisé et en appelant le sélecteur via le code. Cependant, je souhaite utiliser les méthodes UITextFieldDelegate pour la gestion des événements sur le champ de texte. Des hacks, tels que le remplacement du champ de texte par un bouton, ne permettent pas cette approche.

Comment puis-je simplement cacher le curseur sur le UITextField à la place?

120
emenegro

Il suffit de sous-classer UITextField et de remplacer caretRectForPosition

- (CGRect)caretRectForPosition:(UITextPosition *)position
{
    return CGRectZero;
}
258
Joseph Chiu

À partir de iOS 7, vous pouvez maintenant définir le tintColor = [UIColor clearColor] sur le champ de texte et le curseur disparaîtra.

148
jamone

Vous pouvez simplement effacer la teinte du champ de texte

self.textField.tintColor = [UIColor clearColor];

Swift 3.

self.textField.tintColor = .clear

enter image description here

83
oldman

Vous pouvez également empêcher l'utilisateur de sélectionner, de copier ou de coller du texte de sorte que la seule saisie de texte provienne de la vue Sélecteur.

- (CGRect) caretRectForPosition:(UITextPosition*) position
{
    return CGRectZero;
}

- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
    return nil;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(paste:))
    {
        returnNO;
    }

    return [super canPerformAction:action withSender:sender];
}

http://b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/

20
Nat

Découvrez la propriété selectedTextRange du protocole UITextInput , auquel la classe UITextField conforme. Peu! Voilà une leçon de programmation orientée objet.

Masquer le curseur

Pour masquer le curseur, supprimez la plage de texte sélectionnée du champ de texte.

textField.selectedTextRange = nil; // hides caret

Afficher le curseur

Voici deux manières de révéler le curseur.

  1. Définissez la plage de texte sélectionnée du champ de texte à la fin du document.

    UITextPosition *end = textField.endOfDocument;
    textField.selectedTextRange = [textField textRangeFromPosition:end
                                                        toPosition:end];
    
  2. Pour conserver le curseur au même endroit, en premier lieu, stockez la plage de texte sélectionnée du champ de texte dans une variable d'instance.

    _textFieldSelectedTextRange = textField.selectedTextRange;
    textField.selectedTextRange = nil; // hides caret
    

    Ensuite, lorsque vous souhaitez afficher le curseur, réglez simplement la plage de texte sélectionnée dans le champ de texte sur son état d'origine:

    textField.selectedTextRange     = _textFieldSelectedTextRange;
    _textFieldLastSelectedTextRange = nil;
    
14
ma11hew28

Réponse fournie par le PO, copiée du corps de la question pour aider à nettoyer la queue toujours croissante de questions sans réponse.

J'ai trouvé une autre solution: la sous-classe UIButton et substitue ces méthodes

- (UIView *)inputView {
    return inputView_;
}

- (void)setInputView:(UIView *)anInputView {
    if (inputView_ != anInputView) {
        [inputView_ release];
        inputView_ = [anInputView retain];
    }
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

Maintenant, le bouton, en tant que UIResponder, a un comportement similaire à celui de UITextField et une implémentation assez simple.

10
Robert Höglund

Swift 3 version du post de Net

  override func caretRect(for position: UITextPosition) -> CGRect {
    return .zero
  }

  override func selectionRects(for range: UITextRange) -> [Any] {
    return []
  }

  override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return false
  }
5
Rom.

Pour désactiver à la fois le curseur et le menu, j'utilise une sous-classe avec ces 2 méthodes:

- (CGRect)caretRectForPosition:(UITextPosition *)position {
    return CGRectZero;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    [UIMenuController sharedMenuController].menuVisible = NO;
    self.selectedTextRange = nil;

    return NO;
}
1
Vive

Réponse fournie par le PO, copiée du corps de la question pour aider à nettoyer la queue toujours croissante de questions sans réponse.

Je pense avoir la bonne solution, mais si cela peut être amélioré, ce sera la bienvenue :) Bien, j'ai créé une sous-classe de UITextField et surchargé la méthode qui renvoie le CGRect pour les limites

-(CGRect)textRectForBounds:(CGRect)bounds {
    return CGRectZero;
}

Le problème? Le texte ne s'affiche pas car le rect est égal à zéro. Mais j'ai ajouté un UILabel en tant que sous-vue du contrôle et redéfini la méthode setText. Ainsi, lorsque nous saisissons un texte comme d'habitude, le texte du champ de texte est nil et correspond au libellé.

- (void)setText:(NSString *)aText {
    [super setText:nil];

    if (aText == nil) {
        textLabel_.text = nil;
    }

    if (![aText isEqualToString:@""]) {
        textLabel_.text = aText;
    }
}

Avec cela, la chose fonctionne comme prévu. Avez-vous un moyen de l'améliorer?

1
Robert Höglund

définir la teinte sur Couleur claire

textfield.tintColor = [UIColor clearColor];

et vous pouvez également définir à partir du constructeur d'interface

1
Ahmad Al-Attal

Si vous voulez masquer le curseur, vous pouvez facilement l'utiliser! Cela a fonctionné pour moi ..

[[textField valueForKey:@"textInputTraits"] setValue:[UIColor clearColor] forKey:@"insertionPointColor"]
1
Göktuğ Aral

Je sous-classe simplement UITextField et remplace layoutSubviews comme suit:

- (void)layoutSubviews
{
    [super layoutSubviews];
    for (UIView *v in self.subviews)
    {
        if ([[[v class] description] rangeOfString:@"UITextSelectionView"].location != NSNotFound)
        {
            v.hidden = YES;
        }
    }
}

C'est un sale bidouillage, qui pourrait échouer dans le futur (le curseur sera alors visible de nouveau - votre application ne se plantera pas), mais cela fonctionne.

0
Mark Beaton