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?

Alex Catchpole
la source

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])
vacawama
la source
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.

crubio
la source
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

jose920405
la source
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])
Sreedeepkesav MS
la source
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.

Tejinder
la source
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

Krzynool
la source
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)

Ridho Octanio
la source
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!])
        }
    }
}
Khawar Islam
la source
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}];
Álvaro Agüero
la source
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!

Paul Lehn
la source
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
    }
}
ninja_iOS
la source
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!])
        }
    }
}
Dixit Akabari
la source
3

Pour Swift 3 et 3.1, cela fonctionne parfaitement bien:

passField.attributedPlaceholder = NSAttributedString(string: "password", attributes: [NSForegroundColorAttributeName: UIColor.white])
Asfand Shabbir
la source
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])
Ashim Dahal
la source
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.

David Rees
la source
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
iOS Lifee
la source
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])
Anindya
la source
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])
            }
        }
    }
}
Pradip Patel
la source
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!])
    }
}

}
Vikas Rajput
la source
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")
Celil Bozkurt
la source
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/

Andres Paladines
la source
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])
Mr.Javed Multani
la source
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];

Saleh Sultan
la source
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;

}
Jigar Darji
la source
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;
Sureshkumar Linganathan
la source
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!])
                }
            } 
}
Dilip Mishra
la source
-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)
Codewithj
la source
-1

Pour Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
Arjun Dobaria
la source
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])
Durga Ballabha Panigrahi
la source