web-dev-qa-db-fra.com

Comment définir l'espacement des lettres de UITextField

J'ai une application dans laquelle l'utilisateur doit taper un code PIN à quatre chiffres. Tous les chiffres doivent être à une distance définie les uns des autres.

Y a-t-il un moyen de faire cela si PinTextField est une sous-classe de UIView? Je sais que dans une variable ViewController, vous pouvez utiliser UITextFieldTextDidChangeNotification et définir le texte attribué à chaque modification. Les notifications ne semblent pas fonctionner dans un UIView cependant.

Je me demandais également s’il n’existait pas de méthode plus simple que de créer une chaîne attribuée à chaque mise à jour si vous souhaitez définir l’espacement des lettres d’un texte UITextField?

Espacement correct:

 TextField with correct spacing

Mauvais espacement:

 TextField with wrong spacing

31
KMV

C’est ce qui a finalement permis de définir le kern pour chaque changement

    textField.addTarget(self, action: "textFieldDidChange", forControlEvents: .EditingChanged)

    func textFieldDidChange () {    
        let attributedString = NSMutableAttributedString(string: textField.text)
        attributedString.addAttribute(NSKernAttributeName, value: 5, range: NSMakeRange(0, count(textField.text)))
        attributedString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, count(textField.text)))
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor(), range: NSMakeRange(0, count(textField.text)))

        textField.attributedText = attributedString
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

        if count(textField.text) < 4 {
            return true
            // Else if 4 and delete is allowed
        }else if count(string) == 0 {
            return true
            // Else limit reached
        }else{
            return false
        }
    }

Le problème demeure cependant, car les nombres différents ont des largeurs différentes, je reviendrai simplement de créer une UITextField pour chaque chiffre.

8
KMV

Pas besoin d'aller pour attribuéText, qui pour être honnête, était un gâchis implémentant avec un espacement modifié. Dès que j'ai fermé le clavier, l'espacement a disparu, ce qui m'a incité à creuser davantage. 

Chaque UITextField a une propriété appelée defaultTextAttributes, qui selon Apple "renvoie un dictionnaire d'attributs de texte avec des valeurs par défaut.". Le document Apple indique également que "cette propriété applique les attributs spécifiés au texte entier du champ de texte" 

Trouvez simplement un emplacement approprié dans votre code, généralement là où le champ de texte est en cours d'initialisation, puis copiez et collez le texte suivant.

Répondu dans Swift 3.0 

textfield.defaultTextAttributes.updateValue(spacing, forKey: NSKernAttributeName)

où l'espacement est de type CGFloat. Par exemple 2.0

Cela fonctionne également pour différentes polices. 

À votre santé!!


La dernière syntaxe semble être:

 yourField.defaultTextAttributes.updateValue(36.0, 
     forKey: NSAttributedString.Key.kern)
24
iOSer

Utilisez la propriété defaultTextAttributes de UITextField. Il gérera la conversion en NSAttributedString et appliquera les attributs que vous avez définis. Par exemple:

    NSMutableDictionary *attrs = [self.textField.defaultTextAttributes mutableCopy];
[attrs addEntriesFromDictionary:@{
    NSKernAttributeName: @18,
    NSUnderlineColorAttributeName: [UIColor grayColor],
    NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle | NSUnderlinePatternDash)
}];
self.textField.defaultTextAttributes = attrs;
3
Avi

Essayez ce code après avoir défini le délégué dans le champ de texte.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:textField.text];
    [attributedString addAttribute:NSKernAttributeName
                             value:@(5.4)
                             range:NSMakeRange(0, textField.text.length)];
    textField.attributedText = attributedString;
    return YES;
}
0
Vishnuvardhan

Pas vraiment sûr de toute autre solution au lieu d'utiliser une chaîne attribuée.

Mais pour la partie notification, vous pouvez définir le délégué textFields sur UIView et définir la méthode ci-dessous dans la vue. 

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 

La méthode ci-dessus est appelée à chaque fois que le texte saisi dans le champ de texte change.

0
Scarlet

Cela fonctionne très bien dans Swift 2.2. J'espère que cela vous aidera pour l'espacement des lettres dans le champ de texte

override func viewDidLoad() {
 // Do any additional setup after loading the view.
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(SignupVC.limitTextField(_:)), name: "UITextFieldTextDidChangeNotification", object: txtContactNumber)
}
 func limitTextField(Notif:NSNotification) {

    let limit=10;

    let attributedString = NSMutableAttributedString(string: txtContactNumber.text!)
    attributedString.addAttribute(NSKernAttributeName, value: 7, range: NSMakeRange(0, (txtContactNumber.text?.characters.count)!))
   // attributedString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, count(textField.text)))
    attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor(), range: NSMakeRange(0,(txtContactNumber.text?.characters.count)!))

    txtContactNumber.attributedText = attributedString
    if(txtContactNumber.text?.characters.count>limit)
    {
        txtContactNumber.text=txtContactNumber.text?.substringToIndex(limit)
    }
}
0
Arvind Kumar