Modifica del colore del testo segnaposto con Swift


226

Ho un design che implementa un blu scuro UITextField, dato che il testo segnaposto è di default un colore grigio scuro che riesco a malapena a capire cosa dice il testo del segnaposto.

Ovviamente ho cercato su Google il problema, ma devo ancora trovare una soluzione durante l'utilizzo del linguaggio Swift e non di Obj-c.

C'è un modo per cambiare il colore del testo segnaposto in un UITextFieldutilizzo di Swift?

Risposte:


501

È possibile impostare il testo segnaposto utilizzando una stringa attribuita . Passa il colore desiderato con 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])

Per Swift 3+ utilizzare quanto segue:

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

Per Swift 4.2 utilizzare quanto segue:

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

SDK per iOS 11 - la chiave non ha foregroundColor: self.emailTextField? .attributedPlaceholder = NSAttributedString (stringa: "testo segnaposto", attributi: [NSAttributedStringKey.foregroundColor: UIColor.white])
Matthew Ferguson

@MatthewFerguson, l'ho appena provato e funziona. Hai la versione rilasciata di Xcode 9? Di che tipo è emailTextField?
vacawama,

2
@vacawama. Grazie per lo scambio Progetto legacy, aggiornato il mio Xcode dall'App store - Versione 9.0 (9A235) e finalmente trovato la soluzione self.passwordTextField? .AttributedPlaceholder = NSAttributedString (stringa: "PASSWORD", attributi: [NSForegroundColorAttributeName: UIColor.white])
Matthew Ferguson,

3
per l'utilizzo dell'SDK di iOS 11myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName: UIColor.white])
Gema Megantara,

1
C'è un modo per impostare il colore senza impostare la stringa?
ScottyBlades,

285

Puoi farlo rapidamente, senza aggiungere una riga di codice, usando Interface Builder.

Seleziona UITextFielde apri la finestra di ispezione identità sulla destra:

inserisci qui la descrizione dell'immagine

Fai clic sul pulsante più e aggiungi un nuovo attributo di runtime:

placeholderLabel.textColor (Swift 4)

_placeholderLabel.textColor (Swift 3 o meno)

Usa Colore come tipo e seleziona il colore.

Questo è tutto.

Non vedrai il risultato fino a quando non eseguirai di nuovo l'app.


1
vero, ma è una specie di hack, dal momento che la proprietà placeholderLabel.textColor è privata ...
Frédéric Adda,

1
l'app verrà rifiutata dal momento che stiamo usando una proprietà privata della classe?
firecast

2
Sfortunatamente questo non sembra funzionare su iOS 10 almeno.
Nickdnk,

2
@nickdnk Non è vero. In questo momento ho testato su iOS 10.2.1 e funziona. :)
Andrej,

2
Buona strada per crash imprevisti se Apple cambierà l'implementazione interna.)
Vlad

127

Crea UITextFieldun'estensione come questa:

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!])
        }
    }
}

E nel tuo storyboard o .xib. Vedrai

inserisci qui la descrizione dell'immagine


11
⚠️ Avviso: questa estensione si arresta in modo anomalo nel caso in cui decidessi di leggere la proprietà placeHolderColor! Se si restituisce il valore di una proprietà calcolata dal getter della proprietà, il getter verrà richiamato nuovamente dall'interno del getter, determinando una ricorsione infinita. (Vedi: stackoverflow.com/a/42334711/2062785 )
Mischa

1
Per risolvere questo problema e ottenere il comportamento previsto (ovvero il colore segnaposto corretto) ottenere la attributedStringprima lettera (se non vuota) e restituire il colore del testo, altrimenti nil.
Mischa,

perché nella confezione sono mostrati 2 colori? Pensavo fosse per la modalità oscura, ma non era così.
asreerama,

27

In Swift 3.0, utilizzare

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

In Siwft 5.0 + Usa

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

Questo codice funziona in Swift3:

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

fammi sapere se hai qualche problema.


per qualche motivo questo si blocca quando provo a farlo su più di 1 textField. Il primo funziona bene, quindi si arresta in modo anomalo su tutti i campi di testo successivi. Non so perché, ma vorrei poter usare questo metodo poiché è il più semplice e leggibile
Tommy K,

Non è necessario utilizzare setValueper accedere a una proprietà privata. Usa le API pubbliche appropriate.
rmaddy

Questa è la risposta migliore ... Grazie mille.
reza_khalafi,

Xcode 10 / Swift 5 sintassi letterale:#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
Lal Krishna

15

Per impostare il colore segnaposto una volta per tutte UITextFieldnella tua app puoi fare:

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

Questo imposterà il colore desiderato per tutti i TextFieldsegnaposto nell'intera app. Ma è disponibile solo da iOS 9.

Non esiste alcun metodo apparenzaWhenContainedIn .... () prima di iOS 9 in swift ma è possibile utilizzare una delle soluzioni fornite qui in apparenzaWhenContainedIn in Swift


questo cambierà non solo il colore del segnaposto, ma anche il colore del testo.
Timur Suleimanov,

7

Nel mio caso, utilizzo Swift 4

Creo l'estensione per 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 (color: 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
Questo non funzionerà. Il getter causerà una ricorsione infinita.
rmaddy,

2
Funziona benissimo in Swift 4. Ho creato un punto di interruzione nel codice e l'ho verificato.
R. Mohan,

1
NON USARE QUESTO. questo comporterà una ricorsione infinita. prova: stampa (textField.placeHolderColor)
David Rees il

5

Swift 4:

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

Obiettivo-C:

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

4

Ecco la mia rapida implementazione per 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])
    }
}

usare come:

streetTextField?.placeholderColor(AppColor.blueColor)

spero che aiuti qualcuno!


Swift 4.2: self.attributedPlaceholder = NSAttributedString (stringa: placeholderText, attributi: [NSAttributedString.Key.foregroundColor: color])
Sean Stayns

4

Swift 3 (probabilmente 2), puoi ignorare didSet sul segnaposto nella UITextFieldsottoclasse per applicare l'attributo su di esso, in questo modo:

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

Per Swift

Crea estensione UITextField

extension UITextField{

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

Se sei impostato dallo 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

Per Swift 3 e 3.1 funziona perfettamente:

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

3

Per Swift 4.0, versione X-code 9.1 o iOS 11 puoi utilizzare la sintassi seguente per avere un diverso colore segnaposto

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

3

Sono sorpreso di vedere quante scarse soluzioni ci sono qui.

Ecco una versione che funzionerà sempre.

Rapido 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])
        }
    }
}

SUGGERIMENTO : se si modifica il testo segnaposto dopo aver impostato il colore, il colore verrà ripristinato.


3

Basta scrivere sotto il codice nel metodo didFinishLaunchingWithOptions di Appdelegate, utilizzare questo se si desidera modificare l'intera app scritta in Swift 4.2

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


1

Per swift 4.2 e versioni successive puoi farlo come di seguito:

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

1

Nel mio caso, ho fatto quanto segue:

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

Qui sto scrivendo tutti gli UID firmabili di UITextField. Con l'aiuto di questo codice è possibile accedervi direttamente da Inspector file UI nello 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

Per Swift

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

Puoi usarlo;

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

0

Si tratta più di personalizzare il tuo textField ma comunque condividerò questo codice ottenuto da un'altra pagina e lo renderò un po 'migliore:

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]
    )
  }
}

E puoi usarlo in questo modo:

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

Sapendo che hai un UITextFieldcollegato ad un ViewController.

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


0

inserisci qui la descrizione dell'immagine

Per l' obiettivo 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}];

Per Swift :

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

0

Codice obiettivo C per modificare il colore del testo segnaposto.

Per prima cosa importa questa classe objc / runtime -

#import <objc/runtime.h>

quindi sostituisci il nome del tuo campo di testo -

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


0

per 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

Usa così in Swift,

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

Nell'obiettivo 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

Usa questo per aggiungere un segnaposto attribuito:

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

Per Swift 4

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

1
Questo è un duplicato di diverse risposte precedenti. Non è necessario pubblicare risposte duplicate.
rmaddy

-2
yourTextfield.attributedPlaceholder = NSAttributedString(string: "your placeholder text",attributes: [NSForegroundColorAttributeName: UIColor.white])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.