Alterando a cor do texto do espaço reservado com Swift

226

Eu tenho um design que implementa um azul escuro UITextField, pois o texto do espaço reservado é, por padrão, uma cor cinza escuro. Eu mal consigo entender o que o texto do espaço reservado diz.

Pesquisei no Google o problema, é claro, mas ainda tenho que encontrar uma solução enquanto estiver usando a linguagem Swift e não o Obj-c.

Existe uma maneira de alterar a cor do texto do espaço reservado em um UITextFieldSwift?

Alex Catchpole
fonte

Respostas:

501

Você pode definir o texto do espaço reservado usando uma sequência atribuída . Passe a cor desejada com o 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 o Swift 3+, use o seguinte:

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

Para o Swift 4.2, use o seguinte:

myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
Vacawama
fonte
iOS SDK 11 - a chave não tem ForegroundColor: self.emailTextField .attributedPlaceholder = NSAttributedString (string: "texto do espaço reservado", atributos: [NSAttributedStringKey.foregroundColor: UIColor.white])?
Matthew Ferguson
@ MatthewFerguson, eu apenas tentei e funciona. Você tem a versão lançada do Xcode 9? Qual é o tipo de emailTextField?
vacawama
2
@vacawama. Obrigado pela troca. Projeto legado, Atualizei meu Xcode da App Store - Versão 9.0 (9A235) e finalmente surgiu a solução 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
Existe uma maneira de definir a cor sem definir a string?
ScottyBlades
285

Você pode fazer isso rapidamente, sem adicionar uma linha de código, usando o Interface Builder.

Selecione UITextFielde abra o inspetor de identidade à direita:

insira a descrição da imagem aqui

Clique no botão de adição e adicione um novo atributo de tempo de execução:

placeholderLabel.textColor (Swift 4)

_placeholderLabel.textColor (Swift 3 ou menos)

Use Cor como tipo e selecione a cor.

É isso aí.

Você não verá o resultado até executar o aplicativo novamente.

crubio
fonte
1
verdade, mas é um tipo de corte, desde que a propriedade placeholderLabel.textColor é privado ...
Frédéric Adda
1
o aplicativo será rejeitado, pois estamos usando uma propriedade privada da classe?
firecast
2
Infelizmente, isso parece não funcionar pelo menos no iOS 10.
nickdnk
2
@nickdnk Não é verdade. Agora eu testei no iOS 10.2.1 e funciona. :)
Andrej
2
Bom caminho para a queda inesperada se a Apple vai mudar implementação interna).
Vlad
127

Crie uma UITextFieldextensão 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!])
        }
    }
}

E no seu storyboard ou .xib. Você verá

insira a descrição da imagem aqui

jose920405
fonte
11
Warning️ Aviso: esta extensão irá travar o seu programa, caso você decida ler a propriedade placeHolderColor! Se você retornar o valor de uma propriedade computada do getter da propriedade, o getter será chamado novamente de dentro do getter, resultando em uma recursão infinita. (Veja: stackoverflow.com/a/42334711/2062785 )
Mischa
1
Para corrigir isso e obter o comportamento esperado (ou seja, a cor correta do espaço reservado), obtenha a attributedStringprimeira letra (se não estiver vazia) e retorne sua cor de texto, caso contrário nil.
22617 Mischa
Por que duas cores são mostradas na caixa. Eu pensei que era para o modo escuro, mas não era esse o caso.
asreerama 23/01
27

No Swift 3.0, use

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

No 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
fonte
24

Este código está funcionando no Swift3:

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

entre em contato se tiver algum problema.

Tejinder
fonte
por algum motivo, isso trava quando tento fazer isso em mais de 1 textField. O primeiro funciona bem e depois trava em todos os campos de texto subsequentes. Não sei por que, mas eu gostaria de poder usar este método desde a sua o mais fácil e mais legível
Tommy K
Não há necessidade de usar setValuepara acessar uma propriedade privada. Use APIs públicas adequadas.
rmaddy
Esta é a melhor resposta ... Tnx demais.
Reza_khalafi 12/12/19
Sintaxe literal do Xcode 10 / Swift 5:#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
Lal Krishna
15

Para definir a cor do espaço reservado de uma vez por todas UITextFieldno seu aplicativo, você pode:

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

Isso definirá a cor desejada para todos os TextFieldespaços reservados no aplicativo inteiro. Mas só está disponível desde o iOS 9.

Não existe um método antes iOS 9 em rápida appearenceWhenContainedIn .... (), mas você pode usar uma das soluções fornecidas aqui appearanceWhenContainedIn em Swift

Krzynool
fonte
isso mudará não apenas a cor do espaço reservado, mas também a cor do texto.
Timur Suleimanov
7

No meu caso, eu uso o Swift 4

Crio extensão 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
fonte
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
fonte
2
Isso não vai funcionar. O getter causará uma recursão infinita.
rmaddy
2
Isso está funcionando bem no swift 4. Fiz um ponto de interrupção no código e o verifiquei ... a recursão infinita não está acontecendo.
R. Mohan
1
NÃO USE ISTO. isso resultará em recursão infinita. tente: print (textField.placeHolderColor)
David Rees
5

Swift 4:

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

Objetivo-C:

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

Aqui está minha rápida implementação para o 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])
    }
}

use como:

streetTextField?.placeholderColor(AppColor.blueColor)

espero que ajude alguém!

Paul Lehn
fonte
Swift 4.2: self.attributedPlaceholder = NSAttributedString (cadeia: placeholderText, atributos: [NSAttributedString.Key.foregroundColor: cor])
Sean Stayns
4

Swift 3 (provavelmente 2), você pode substituir didSet no espaço reservado na UITextFieldsubclasse para aplicar o atributo desta forma:

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

Para Swift

Criar extensão UITextField

extension UITextField{

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

Se você está definido no 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
fonte
3

Para Swift 3 e 3.1, isso funciona perfeitamente:

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

No Swift 4.0, versão X-code 9.1 ou iOS 11, você pode usar a seguinte sintaxe para ter cores diferentes no espaço reservado

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

Estou surpreso ao ver quantas soluções ruins existem aqui.

Aqui está uma versão que sempre 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])
        }
    }
}

DICA : Se você alterar o texto do espaço reservado após definir a cor, a cor será redefinida.

David Rees
fonte
3

Basta escrever o código abaixo no método didFinishLaunchingWithOptions do Appdelegate, use-o se desejar alterar todo o aplicativo escrito no Swift 4.2

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

atualização de resposta de crubio para Swift 4

Selecione o UITextField e abra o inspetor de identidade à direita:

Clique no botão mais e adicione um novo atributo de tempo de execução: placeholderLabel.textColor (em vez de _placeholderLabel.textColor)

Use Cor como tipo e selecione a cor.

Se você executar seu projeto, verá as alterações.

Dris
fonte
1

Para o Swift 4.2 e superior, você pode fazer o seguinte:

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

No meu caso, eu fiz o seguinte:

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

Aqui estou escrevendo tudo UIDesignable de UITextField. Com a ajuda desse código, você pode acessá-lo diretamente do arquivo UI Inspector no 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
fonte
0

Para Swift

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

Você pode usar isso;

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

É mais uma questão de personalizar o seu textField, mas de qualquer forma, compartilharei esse código obtido em outra página e o tornei um pouco melhor:

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 você pode usá-lo assim:

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

Sabendo que você tem um UITextFieldconectado a ViewController.

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

Andres Paladines
fonte
0

insira a descrição da imagem aqui

Para o 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])
Mr.Javed Multani
fonte
0

Código C do objetivo para alterar a cor do texto do espaço reservado.

Primeiro importe esta classe objc / runtime -

#import <objc/runtime.h>

substitua seu nome do campo de texto -

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

Saleh Sultan
fonte
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
fonte
0

Use assim no Swift,

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

No 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
fonte
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
fonte
-1

Use isso para adicionar um espaço reservado atribuído:

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

Para Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
Arjun Dobaria
fonte
1
Esta é uma duplicata de várias respostas anteriores. Não há necessidade de postar respostas duplicadas.
rmaddy
-2
yourTextfield.attributedPlaceholder = NSAttributedString(string: "your placeholder text",attributes: [NSForegroundColorAttributeName: UIColor.white])
Durga Ballabha Panigrahi
fonte