Cambio del color del texto del marcador de posición con Swift

226

Tengo un diseño que implementa un azul oscuro UITextField , ya que el texto del marcador de posición es por defecto un color gris oscuro que apenas puedo distinguir lo que dice el texto del marcador de posición.

He buscado en Google el problema, por supuesto, pero todavía tengo que encontrar una solución mientras uso el lenguaje Swift y no Obj-c.

¿Hay alguna manera de cambiar el color del texto del marcador de posición UITextFieldusando Swift?

Alex Catchpole
fuente

Respuestas:

501

Puede establecer el texto del marcador de posición utilizando una cadena atribuida . Pase el color que desee 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])

Para Swift 3+ use lo siguiente:

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

Para Swift 4.2 use lo siguiente:

myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
vacawama
fuente
iOS 11 SDK: la clave no tiene color de primer plano: self.emailTextField? .attributedPlaceholder = NSAttributedString (cadena: "texto de marcador de posición", atributos: [NSAttributedStringKey.foregroundColor: UIColor.white])
Matthew Ferguson
@MatthewFerguson, acabo de probarlo y funciona. ¿Tienes la versión lanzada de Xcode 9? ¿De qué tipo es emailTextField?
vacawama
2
@vacawama. Gracias por el intercambio. Proyecto heredado, actualicé mi Xcode de la tienda de aplicaciones - Versión 9.0 (9A235), y finalmente se me ocurrió la solución self.passwordTextField? .AttributedPlaceholder = NSAttributedString (string: "PASSWORD", atributos: [NSForegroundColorAttributeName: UIColor.white])
Matthew Ferguson
3
para iOS 11 SDK usemyTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName: UIColor.white])
Gema Megantara
1
¿Hay alguna manera de configurar el color sin configurar la cadena?
ScottyBlades
285

Puede lograr esto rápidamente, sin agregar una línea de código, utilizando Interface Builder.

Seleccione UITextFieldy abra el inspector de identidad a la derecha:

enter image description here

Haga clic en el botón más y agregue un nuevo atributo de tiempo de ejecución:

placeholderLabel.textColor (Swift 4)

_placeholderLabel.textColor (Swift 3 o menos)

Use Color como tipo y seleccione el color.

Eso es.

No verá el resultado hasta que vuelva a ejecutar su aplicación.

crubio
fuente
1
cierto, pero es una especie de pirateo, ya que la propiedad placeholderLabel.textColor es privada ...
Frédéric Adda
1
¿se rechazará la aplicación ya que estamos usando una propiedad privada de la clase?
Firecast 01 de
2
Lamentablemente, esto no parece funcionar en iOS 10 al menos.
nickdnk
2
@nickdnk No es cierto. En este momento lo he probado en iOS 10.2.1 y funciona. :)
Andrej
2
Buen camino hacia un choque inesperado si Apple cambia la implementación interna.)
Vlad
127

Crea una UITextFieldextensión como esta:

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

Y en tu guión gráfico o .xib. Ya verás

ingrese la descripción de la imagen aquí

jose920405
fuente
11
⚠️ Advertencia: ¡ Esta extensión bloqueará su programa si alguna vez decide leer la propiedad placeHolderColor! Si devuelve el valor de una propiedad calculada del getter de la propiedad, se llamará nuevamente al getter desde dentro del getter, lo que dará como resultado una recursión infinita. (Ver: stackoverflow.com/a/42334711/2062785 )
Mischa
1
Para solucionar esto y obtener el comportamiento esperado (es decir, el color correcto del marcador de posición), obtenga la attributedStringprimera letra de la letra (si no está vacía) y devuelva su color de texto, de lo contrario nil.
Mischa
¿Por qué se muestran 2 colores en el cuadro? Pensé que esto era para el modo oscuro, pero ese no era el caso.
asreerama
27

En Swift 3.0, use

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

En Siwft 5.0 + Uso

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
fuente
24

Este código está funcionando en Swift3:

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

Avísame si tienes algún problema.

Tejinder
fuente
por alguna razón, esto se bloquea cuando intento hacerlo en más de 1 textField. El primero funciona bien y luego se bloquea en todos los campos de texto posteriores. No estoy seguro de por qué, pero desearía poder usar este método, ya que es el más fácil y legible
Tommy K
No es necesario usar setValuepara acceder a una propiedad privada. Utilice las API públicas adecuadas.
rmaddy
Esta es la mejor respuesta ... Tnx mucho.
reza_khalafi
Xcode 10 / Swift 5 sintaxis literal:#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
Lal Krishna
15

Para configurar el color del marcador de posición de una vez para todo lo UITextFieldque puede hacer en su aplicación:

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

Esto establecerá el color deseado para todos los TextFieldmarcadores de posición en toda la aplicación. Pero solo está disponible desde iOS 9.

No hay un método de apariciónWhenContainedIn .... () antes de iOS 9 en Swift, pero puede usar una de las soluciones proporcionadas aquí apariciónWhenContainedIn en Swift

Krzynool
fuente
esto cambiará no solo el color del marcador de posición, sino también el color del texto.
Timur Suleimanov
7

En mi caso, uso Swift 4

Creo una extensión para 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)

Ridho Octanio
fuente
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
fuente
2
Esto no funcionara. El captador causará una recursión infinita.
rmaddy
2
Esto está funcionando bien en Swift 4. Hice un punto de interrupción en el código y lo verifiqué ... no ocurre recursión infinita.
R. Mohan
1
NO UTILICE ESTO. Esto dará como resultado una recursión infinita. try: print (textField.placeHolderColor)
David Rees
5

Swift 4:

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

C objetivo :

UIColor *color = [UIColor grayColor];
txtControl.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Placeholder String..." attributes:@{NSForegroundColorAttributeName: color}];
Álvaro Agüero
fuente
4

Aquí está mi implementación rápida para 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])
    }
}

usar como:

streetTextField?.placeholderColor(AppColor.blueColor)

Espero que ayude a alguien!

Paul Lehn
fuente
Swift 4.2: self.attributedPlaceholder = NSAttributedString (cadena: placeholderText, atributos: [NSAttributedString.Key.foregroundColor: color])
Sean Stayns
4

Swift 3 (probablemente 2), puede anular didSet en el marcador de posición en la UITextFieldsubclase para aplicar el atributo de esta manera:

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
fuente
4

Para Swift

Crear extensión UITextField

extension UITextField{

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

Si está establecido desde el guión gráfico.

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
fuente
3

Para Swift 3 y 3.1 esto funciona perfectamente bien:

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

Para Swift 4.0, versión X-code 9.1 o iOS 11 , puede usar la siguiente sintaxis para tener un color de marcador de posición diferente

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

Me sorprende ver cuántas soluciones pobres hay aquí.

Aquí hay una versión que siempre funcionará.

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

CONSEJO : Si cambia el texto del marcador de posición después de configurar el color, el color se restablecerá.

David Rees
fuente
3

Simplemente escriba el código a continuación en el método didFinishLaunchingWithOptions de Appdelegate, use esto si desea cambiar en toda la aplicación escrita en Swift 4.2

UILabel.appearance(whenContainedInInstancesOf: [UITextField.self]).textColor = UIColor.white
iOS Lifee
fuente
1

actualización de la respuesta de crubio para Swift 4

Seleccione UITextField y abra el inspector de identidad a la derecha:

Haga clic en el botón más y agregue un nuevo atributo de tiempo de ejecución: placeholderLabel.textColor (en lugar de _placeholderLabel.textColor)

Use Color como tipo y seleccione el color.

Si ejecuta su proyecto, verá los cambios.

Dris
fuente
1

Para swift 4.2 y superior, puede hacerlo de la siguiente manera:

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

En mi caso, he hecho lo siguiente:

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
fuente
1

Aquí estoy escribiendo todos los UIDesignable de UITextField. Con la ayuda de este código, puede acceder directamente desde el inspector de archivos de la interfaz de usuario en el guión gráfico

@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
fuente
0

Para Swift

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

Puedes usar esto;

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

Se trata más de personalizar tu textField, pero de todos modos compartiré este código que obtuve de otra página y lo hice un poco mejor:

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

Y puedes usarlo así:

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

Sabiendo que tienes un UITextFieldconectado a ViewController.

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

Andres Paladines
fuente
0

ingrese la descripción de la imagen aquí

Para el objetivo 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}];

Para Swift :

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

Código objetivo C para cambiar el color del texto del marcador de posición.

Primero importe esta clase objc / runtime -

#import <objc/runtime.h>

luego reemplace su nombre de campo de texto -

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

Saleh Sultan
fuente
0

para 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
fuente
0

Úselo así en Swift,

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

En el objetivo C

NSString *placeHolder = [textField.placeholder length]>0 ? textField.placeholder: @"";
NSAttributedString *str = [[NSAttributedString alloc] initWithString:placeHolder attributes:@{ NSForegroundColorAttributeName : [UIColor lightGrayColor] }];
textField.attributedPlaceholder = str;
Sureshkumar Linganathan
fuente
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
fuente
-1

Use esto para agregar un marcador de posición atribuido:

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
fuente
-1

Para Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
Arjun Dobaria
fuente
1
Este es un duplicado de varias respuestas anteriores. No es necesario publicar respuestas duplicadas.
rmaddy
-2
yourTextfield.attributedPlaceholder = NSAttributedString(string: "your placeholder text",attributes: [NSForegroundColorAttributeName: UIColor.white])
Durga Ballabha Panigrahi
fuente