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?
Il suffit de sous-classer UITextField et de remplacer caretRectForPosition
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
return CGRectZero;
}
À partir de iOS 7, vous pouvez maintenant définir le tintColor = [UIColor clearColor]
sur le champ de texte et le curseur disparaîtra.
Vous pouvez simplement effacer la teinte du champ de texte
self.textField.tintColor = [UIColor clearColor];
Swift 3.
self.textField.tintColor = .clear
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/
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.
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];
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;
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.
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
}
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;
}
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?
définir la teinte sur Couleur claire
textfield.tintColor = [UIColor clearColor];
et vous pouvez également définir à partir du constructeur d'interface
Si vous voulez masquer le curseur, vous pouvez facilement l'utiliser! Cela a fonctionné pour moi ..
[[textField valueForKey:@"textInputTraits"] setValue:[UIColor clearColor] forKey:@"insertionPointColor"]
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.