Modification de la couleur du texte de l'espace réservé avec Swift


226

J'ai un design qui implémente un bleu foncé UITextField, car le texte de l'espace réservé est par défaut une couleur gris foncé, je peux à peine distinguer ce que dit le texte de l'espace réservé.

J'ai googlé le problème bien sûr, mais je n'ai pas encore trouvé de solution en utilisant le langage Swift et non Obj-c.

Existe-t-il un moyen de modifier la couleur du texte de l'espace réservé dans un UITextFieldSwift à l'aide?

Réponses:


501

Vous pouvez définir le texte de l'espace réservé à l'aide d'une chaîne attribuée . Passez la couleur que vous voulez avec attributes:

var myTextField = UITextField(frame: CGRect(x: 0, y: 0, width: 200, height: 30))
myTextField.backgroundColor = .blue
myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSForegroundColorAttributeName: UIColor.yellow])

Pour Swift 3+, utilisez les éléments suivants:

myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])

Pour Swift 4.2, utilisez les éléments suivants:

myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])

Kit de développement logiciel (SDK) iOS 11 - la clé n'a pas de premier plan: self.emailTextField? .attributedPlaceholder = NSAttributedString (chaîne: "texte d'espace réservé", attributs: [NSAttributedStringKey.foregroundColor: UIColor.white])
Matthew Ferguson

@MatthewFerguson, je viens de l'essayer et ça marche. Avez-vous la version finale de Xcode 9? Quel est le type de emailTextField?
vacawama

2
@vacawama. Merci pour l'échange. Projet hérité, mis à jour mon Xcode depuis l'App Store - version 9.0 (9A235), et finalement trouvé la solution de self.passwordTextField? .AttributedPlaceholder = NSAttributedString (chaîne: "PASSWORD", attributs: [NSForegroundColorAttributeName: UIColor.white])
Matthew Ferguson

3
pour l'utilisation du SDK iOS 11myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName: UIColor.white])
Gema Megantara

1
Existe-t-il un moyen de définir la couleur sans définir la chaîne?
ScottyBlades

286

Vous pouvez accomplir cela rapidement, sans ajouter de ligne de code, en utilisant Interface Builder.

Sélectionnez UITextFieldet ouvrez l'inspecteur d'identité sur la droite:

entrez la description de l'image ici

Cliquez sur le bouton plus et ajoutez un nouvel attribut d'exécution:

placeholderLabel.textColor (Swift 4)

_placeholderLabel.textColor (Swift 3 ou moins)

Utilisez Couleur comme type et sélectionnez la couleur.

C'est tout.

Vous ne verrez pas le résultat jusqu'à ce que vous exécutiez à nouveau votre application.


1
vrai, mais c'est une sorte de hack, puisque la propriété placeholderLabel.textColor est privée ...
Frédéric Adda

1
l'application sera-t-elle rejetée puisque nous utilisons une propriété privée de la classe?
Firecast

2
Malheureusement, cela ne semble pas fonctionner sur iOS 10 au moins.
nickdnk

2
@nickdnk Pas vrai. En ce moment, j'ai testé sur iOS 10.2.1 et cela fonctionne. :)
Andrej

2
Bonne route vers un crash inattendu si Apple change d'implémentation interne.)
Vlad

127

Créez une UITextFieldextension comme celle-ci:

extension UITextField{
   @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: newValue!])
        }
    }
}

Et dans votre storyboard ou .xib. Tu verras

entrez la description de l'image ici


11
⚠️ Avertissement: cette extension plantera votre programme si vous décidez de lire la propriété placeHolderColor! Si vous renvoyez la valeur d'une propriété calculée elle-même à partir du getter de la propriété, le getter sera à nouveau appelé depuis l'intérieur du getter, ce qui entraînera une récursion infinie. (Voir: stackoverflow.com/a/42334711/2062785 )
Mischa

1
Pour résoudre ce problème et obtenir le comportement attendu (c'est-à-dire la couleur d'espace réservé correcte), récupérez la attributedStringpremière lettre de (sinon vide) et renvoyez sa couleur de texte, sinon nil.
Mischa

pourquoi 2 couleurs sont-elles affichées dans la boîte. Je pensais que c'était pour le mode sombre mais ce n'était pas le cas.
asreerama

27

Dans Swift 3.0, utilisez

let color = UIColor.lightText
textField.attributedPlaceholder = NSAttributedString(string: textField.placeholder, attributes: [NSForegroundColorAttributeName : color])

Dans Siwft 5.0 + Use

let color = UIColor.lightText
let placeholder = textField.placeholder ?? "" //There should be a placeholder set in storyboard or elsewhere string or pass empty
textField.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor : color])

24

Ce code fonctionne dans Swift3:

yourTextFieldName .setValue(UIColor.init(colorLiteralRed: 80/255, green: 80/255, blue: 80/255, alpha: 1.0), forKeyPath: "_placeholderLabel.textColor")

faites-moi savoir si vous avez un problème.


pour une raison quelconque, cela se bloque lorsque j'essaie de le faire pour plus de 1 textField. Le premier fonctionne correctement, puis il se bloque sur tous les textFields suivants. Je ne sais pas pourquoi mais j'aimerais pouvoir utiliser cette méthode car c'est la plus simple et la plus lisible
Tommy K

Il n'est pas nécessaire d'utiliser setValuepour accéder à une propriété privée. Utilisez des API publiques appropriées.
rmaddy

C'est la meilleure réponse ... Tnx tellement.
reza_khalafi

Syntaxe littérale Xcode 10 / Swift 5:#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
Lal Krishna

15

Pour définir la couleur de l'espace réservé une fois pour toutes UITextFielddans votre application, vous pouvez faire:

UILabel.appearanceWhenContainedInInstancesOfClasses([UITextField.self]).textColor = UIColor.redColor()

Cela définira la couleur souhaitée pour tous les TextFieldespaces réservés dans l'application entière. Mais il n'est disponible que depuis iOS 9.

Il n'y a pas de méthode l'apparenceWhenContainedIn .... () avant iOS 9 dans swift mais vous pouvez utiliser l'une des solutions fournies ici apparenceWhenContainedIn dans Swift


cela changera non seulement la couleur de l'espace réservé, mais aussi la couleur du texte.
Timur Suleimanov

7

Dans mon cas, j'utilise Swift 4

Je crée une extension pour UITextField

extension UITextField {
    func placeholderColor(color: UIColor) {
        let attributeString = [
            NSAttributedStringKey.foregroundColor: color.withAlphaComponent(0.6),
            NSAttributedStringKey.font: self.font!
            ] as [NSAttributedStringKey : Any]
        self.attributedPlaceholder = NSAttributedString(string: self.placeholder!, attributes: attributeString)
    }
}

yourField.placeholderColor (couleur: UIColor.white)


6

Xcode 9.2 Swift 4

extension UITextField{
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedStringKey.foregroundColor: newValue!])
        }
    }
}

2
Ça ne marchera pas. Le getter provoquera une récursion infinie.
rmaddy

2
Cela fonctionne bien dans swift 4. J'ai fait un point d'arrêt dans le code et l'ai vérifié ... la récursion infinie ne se produit pas.
R. Mohan

1
N'UTILISEZ PAS CELA. cela entraînera une récursion infinie. essayer: imprimer (textField.placeHolderColor)
David Rees

5

Swift 4:

txtControl.attributedPlaceholder = NSAttributedString(string: "Placeholder String...",attributes: [NSAttributedStringKey.foregroundColor: UIColor.gray])

Objectif c :

UIColor *color = [UIColor grayColor];
txtControl.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Placeholder String..." attributes:@{NSForegroundColorAttributeName: color}];

4

Voici ma mise en œuvre rapide pour swift 4:

extension UITextField {
    func placeholderColor(_ color: UIColor){
        var placeholderText = ""
        if self.placeholder != nil{
            placeholderText = self.placeholder!
        }
        self.attributedPlaceholder = NSAttributedString(string: placeholderText, attributes: [NSAttributedStringKey.foregroundColor : color])
    }
}

utiliser comme:

streetTextField?.placeholderColor(AppColor.blueColor)

j'espère que ça aide quelqu'un!


Swift 4.2: self.attributedPlaceholder = NSAttributedString (chaîne: placeholderText, attributs: [NSAttributedString.Key.foregroundColor: color])
Sean Stayns

4

Swift 3 (probablement 2), vous pouvez remplacer didSet sur l'espace réservé dans la UITextFieldsous-classe pour lui appliquer un attribut, de cette façon:

override var placeholder: String? {

    didSet {
        guard let tmpText = placeholder else {
            self.attributedPlaceholder = NSAttributedString(string: "")
            return
        }

        let textRange = NSMakeRange(0, tmpText.characters.count)
        let attributedText = NSMutableAttributedString(string: tmpText)
        attributedText.addAttribute(NSForegroundColorAttributeName , value:UIColor(white:147.0/255.0, alpha:1.0), range: textRange)

        self.attributedPlaceholder = attributedText
    }
}

4

Pour Swift

Créer l'extension UITextField

extension UITextField{

    func setPlaceHolderColor(){
        self.attributedPlaceholder = NSAttributedString(string: self.placeholder!, attributes: [NSForegroundColorAttributeName : UIColor.white])
    }
}

Si vous êtes défini à partir du storyboard.

extension UITextField{
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            return self.placeHolderColor
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor : newValue!])
        }
    }
}

3

Pour Swift 3 et 3.1, cela fonctionne parfaitement bien:

passField.attributedPlaceholder = NSAttributedString(string: "password", attributes: [NSForegroundColorAttributeName: UIColor.white])

3

Pour Swift 4.0, la version X-code 9.1 ou iOS 11, vous pouvez utiliser la syntaxe suivante pour avoir une couleur d'espace réservé différente

textField.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes: [NSAttributedStringKey.foregroundColor : UIColor.white])

3

Je suis surpris de voir combien de mauvaises solutions il y a ici.

Voici une version qui fonctionnera toujours.

Swift 4.2

extension UITextField{
    @IBInspectable var placeholderColor: UIColor {
        get {
            return self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor ?? .lightText
        }
        set {
            self.attributedPlaceholder = NSAttributedString(string: self.placeholder ?? "", attributes: [.foregroundColor: newValue])
        }
    }
}

CONSEIL : Si vous modifiez le texte de l'espace réservé après avoir défini la couleur, la couleur sera réinitialisée.


3

Écrivez simplement le code ci-dessous dans la méthode didFinishLaunchingWithOptions d'Appdelegate, utilisez-la si vous voulez changer dans l'application entière écrite dans Swift 4.2

UILabel.appearance(whenContainedInInstancesOf: [UITextField.self]).textColor = UIColor.white


1

Pour swift 4.2 et supérieur, vous pouvez le faire comme ci-dessous:

textField.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])

1

Dans mon cas, j'ai fait ce qui suit:

extension UITextField {
    @IBInspectable var placeHolderColor: UIColor? {
        get {
            if let color = self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor {
                return color
            }
            return nil
        }
        set (setOptionalColor) {
            if let setColor = setOptionalColor {
                let string = self.placeholder ?? ""
                self.attributedPlaceholder = NSAttributedString(string: string , attributes:[NSAttributedString.Key.foregroundColor: setColor])
            }
        }
    }
}

1

Ici j'écris tous les UIDesignable de UITextField. Avec l'aide de ce code, vous pouvez y accéder directement depuis l'inspecteur de fichiers d'interface utilisateur dans le storyboard

@IBDesignable
class CustomTextField: UITextField {

@IBInspectable var leftImage: UIImage? {
    didSet {
        updateView()
    }
}

@IBInspectable var leftPadding: CGFloat = 0 {
    didSet {
        updateView()
    }
}

@IBInspectable var rightImage: UIImage? {
    didSet {
        updateView()
    }
}

@IBInspectable var rightPadding: CGFloat = 0 {
    didSet {
        updateView()
    }
}

private var _isRightViewVisible: Bool = true
var isRightViewVisible: Bool {
    get {
        return _isRightViewVisible
    }
    set {
        _isRightViewVisible = newValue
        updateView()
    }
}

func updateView() {
    setLeftImage()
    setRightImage()

    // Placeholder text color
    attributedPlaceholder = NSAttributedString(string: placeholder != nil ?  placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: tintColor])
}

func setLeftImage() {
    leftViewMode = UITextField.ViewMode.always
    var view: UIView

    if let image = leftImage {
        let imageView = UIImageView(frame: CGRect(x: leftPadding, y: 0, width: 20, height: 20))
        imageView.image = image
        // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
        imageView.tintColor = tintColor

        var width = imageView.frame.width + leftPadding

        if borderStyle == UITextField.BorderStyle.none || borderStyle == UITextField.BorderStyle.line {
            width += 5
        }

        view = UIView(frame: CGRect(x: 0, y: 0, width: width, height: 20))
        view.addSubview(imageView)
    } else {
        view = UIView(frame: CGRect(x: 0, y: 0, width: leftPadding, height: 20))
    }

    leftView = view
}

func setRightImage() {
    rightViewMode = UITextField.ViewMode.always

    var view: UIView

    if let image = rightImage, isRightViewVisible {
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        imageView.image = image
        // Note: In order for your image to use the tint color, you have to select the image in the Assets.xcassets and change the "Render As" property to "Template Image".
        imageView.tintColor = tintColor

        var width = imageView.frame.width + rightPadding

        if borderStyle == UITextField.BorderStyle.none || borderStyle == UITextField.BorderStyle.line {
            width += 5
        }

        view = UIView(frame: CGRect(x: 0, y: 0, width: width, height: 20))
        view.addSubview(imageView)

    } else {
        view = UIView(frame: CGRect(x: 0, y: 0, width: rightPadding, height: 20))
    }

    rightView = view
}


@IBInspectable public var borderColor: UIColor = UIColor.clear {
    didSet {
        layer.borderColor = borderColor.cgColor
    }
}

@IBInspectable public var borderWidth: CGFloat = 0 {
    didSet {
        layer.borderWidth = borderWidth
    }
}

@IBInspectable public var cornerRadius: CGFloat = 0 {
    didSet {
        layer.cornerRadius = cornerRadius
    }
}
@IBInspectable public var bottomBorder: CGFloat = 0 {
    didSet {
       borderStyle = .none
        layer.backgroundColor = UIColor.white.cgColor

        layer.masksToBounds = false
     //   layer.shadowColor = UIColor.gray.cgColor
        layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
        layer.shadowOpacity = 1.0
        layer.shadowRadius = 0.0
    }
}
@IBInspectable public var bottomBorderColor : UIColor = UIColor.clear {
    didSet {

        layer.shadowColor = bottomBorderColor.cgColor
        layer.shadowOffset = CGSize(width: 0.0, height: 1.0)
        layer.shadowOpacity = 1.0
        layer.shadowRadius = 0.0
    }
}
/// Sets the placeholder color
@IBInspectable var placeHolderColor: UIColor? {
    get {
        return self.placeHolderColor
    }
    set {
        self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "", attributes:[NSAttributedString.Key.foregroundColor: newValue!])
    }
}

}

0

Pour Swift

func setPlaceholderColor(textField: UITextField, placeholderText: String) {
    textField.attributedPlaceholder = NSAttributedString(string: placeholderText, attributes: [NSForegroundColorAttributeName: UIColor.pelorBlack])
}

Vous pouvez l'utiliser;

self.setPlaceholderColor(textField: self.emailTextField, placeholderText: "E-Mail/Username")

0

Il s'agit plus de personnaliser votre textField mais de toute façon je partagerai ce code obtenu sur une autre page et le rendrai un peu mieux:

import UIKit
extension UITextField {
func setBottomLine(borderColor: UIColor, fontColor: UIColor, placeHolderColor:UIColor, placeHolder: String) {
    self.borderStyle = UITextBorderStyle.none
    self.backgroundColor = UIColor.clear
    let borderLine = UIView()
    let height = 1.0
    borderLine.frame = CGRect(x: 0, y: Double(self.frame.height) - height, width: Double(self.frame.width), height: height)
    self.textColor = fontColor
    borderLine.backgroundColor = borderColor
    self.addSubview(borderLine)
    self.attributedPlaceholder = NSAttributedString(
        string: placeHolder,
        attributes: [NSAttributedStringKey.foregroundColor: placeHolderColor]
    )
  }
}

Et vous pouvez l'utiliser comme ceci:

self.textField.setBottomLine(borderColor: lineColor, fontColor: fontColor, placeHolderColor: placeHolderColor, placeHolder: placeHolder)

Sachant que vous êtes UITextFieldconnecté à un ViewController.

Source: http://codepany.com/blog/swift-3-custom-uitextfield-with-single-line-input/


0

entrez la description de l'image ici

Pour l' objectif C :

UIColor *color = [UIColor colorWithRed:0.44 green:0.44 blue:0.44 alpha:1.0];
 emailTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Friend's Email" attributes:@{NSForegroundColorAttributeName: color}];

Pour Swift :

emailTextField.attributedPlaceholder = NSAttributedString(string: "Friend's Email",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])

0

Code objectif C pour changer la couleur du texte de l'espace réservé.

Importez d'abord cette classe objc / runtime -

#import <objc/runtime.h>

puis remplacez votre nom de champ de texte -

Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
UILabel *placeholderLabel = object_getIvar(YourTxtField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];


0

pour iOS13

+(void)ChangeplaceholderColor :(UITextField *)TxtFld andColor:(UIColor*)color { 
    NSMutableAttributedString *placeholderAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:TxtFld.attributedPlaceholder];
       [placeholderAttributedString addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, [placeholderAttributedString length])];
       TxtFld.attributedPlaceholder = placeholderAttributedString;

}

0

Utilisez comme ça dans Swift,

 let placeHolderText = textField.placeholder ?? ""
 let str = NSAttributedString(string:placeHolderText!, attributes: [NSAttributedString.Key.foregroundColor :UIColor.lightGray])
 textField.attributedPlaceholder = str

Dans l'objectif C

NSString *placeHolder = [textField.placeholder length]>0 ? textField.placeholder: @"";
NSAttributedString *str = [[NSAttributedString alloc] initWithString:placeHolder attributes:@{ NSForegroundColorAttributeName : [UIColor lightGrayColor] }];
textField.attributedPlaceholder = str;

0
    extension UITextField{
            @IBInspectable var placeHolderColor: UIColor? {
                get {
                    return self.placeHolderColor
                }
                set {
                    self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ?
        self.placeholder! : "",
        attributes:[NSAttributedString.Key.foregroundColor : newValue!])
                }
            } 
}

-1

Utilisez-le pour ajouter un espace réservé attribué:

let attributes : [String : Any]  = [ NSForegroundColorAttributeName: UIColor.lightGray,
                                     NSFontAttributeName : UIFont(name: "Helvetica Neue Light Italic", size: 12.0)!
                                   ]
x_textfield.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes:attributes)

-1

Pour Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])

1
Il s'agit d'un doublon de plusieurs réponses antérieures. Pas besoin de poster des réponses en double.
rmaddy

-2
yourTextfield.attributedPlaceholder = NSAttributedString(string: "your placeholder text",attributes: [NSForegroundColorAttributeName: UIColor.white])
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.