289

I have a design that implements a dark blue UITextField, as the placeholder text is by default a dark grey colour I can barely make out what the place holder text says.

I've googled the problem of course but I have yet to come up with a solution while using the Swift language and not Obj-c.

Is there a way to change the placeholder text colour in a UITextField using Swift?

Kuldeep
  • 4,466
  • 8
  • 32
  • 59
Alex Catchpole
  • 7,156
  • 6
  • 20
  • 29

32 Answers32

639

You can set the placeholder text using an attributed string. Just pass the color you want to the attributes parameter.

Swift 5:

let myTextField = UITextField(frame: CGRect(x: 0, y: 0, width: 200, height: 30))
myTextField.backgroundColor = .blue
myTextField.attributedPlaceholder = NSAttributedString(
    string: "Placeholder Text",
    attributes: [NSAttributedString.Key.foregroundColor: UIColor.white]
)

Swift 3:

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

Older Swift:

myTextField.attributedPlaceholder = NSAttributedString(
    string: "Placeholder Text",
    attributes: [NSForegroundColorAttributeName: UIColor.white]
)
aheze
  • 24,434
  • 8
  • 68
  • 125
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • iOS 11 SDK - the key has no foregroundColor : self.emailTextField?.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white]) – Matthew Ferguson Sep 26 '17 at 19:59
  • @MatthewFerguson, I just tried it and it works. Do you have the released version of Xcode 9? What is the type of `emailTextField` ? – vacawama Sep 26 '17 at 20:17
  • 2
    @vacawama . Thanks for the exchange. Legacy project, Updated my Xcode from the App store - Version 9.0 (9A235), and finally came up with the solution of self.passwordTextField?.attributedPlaceholder = NSAttributedString(string: "PASSWORD", attributes: [NSForegroundColorAttributeName: UIColor.white]) – Matthew Ferguson Sep 27 '17 at 20:51
  • 3
    for iOS 11 SDK use `myTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName: UIColor.white])` – Gema Megantara Oct 18 '17 at 07:13
  • 3
    Is there a way to set the color without setting the string? – ScottyBlades Aug 02 '18 at 17:52
  • 1
    @ScottyBlades, you have to set the color with the string. If you want to change the color of the current attributed string, get the current string and use it to create a new one: `myTextField.attributedPlaceholder = NSAttributedString(string: myTextField.attributedPlaceholder?.string ?? "", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])` – vacawama Aug 02 '18 at 18:20
325

You can accomplish this quickly, without adding a line of code, using Interface Builder.

Select the UITextField and open the identity inspector on the right:

enter image description here

Click on the plus button and add a new runtime attribute:

placeholderLabel.textColor (Swift 4)

_placeholderLabel.textColor (Swift 3 or less)

Use Color as type and select the color.

That's it.

You wont see the result until you run your app again.

crubio
  • 6,394
  • 4
  • 30
  • 33
  • 4
    true, but it is a kind of hack, since the placeholderLabel.textColor property is private ... – Frederic Adda Oct 09 '15 at 19:27
  • What do you mean with "multiple textfiield" @Kiranjadhav? You could define the placeholder for each textfield. – crubio Aug 16 '17 at 07:37
  • 3
    Good road to unexpected crash if Apple will change internal implementation .) – Vlad Aug 20 '17 at 17:42
  • Working in iOS 12, Xcode 10, the common problem i faced after connection is i have to re-connect the view controller again to a specific view. then it will work, the problem statement is as below error name: "this class is not key value coding-compliant for the key keyPath" – Abuzar Manzoor Oct 09 '18 at 06:12
143

Create UITextField Extension like this:

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

And in your storyboard or .xib. You will see

enter image description here

Kiran Jasvanee
  • 6,362
  • 1
  • 36
  • 52
jose920405
  • 7,982
  • 6
  • 45
  • 71
  • 14
    ⚠️ **Warning:** This extension will **crash** your program should you ever decide to _read_ the property `placeHolderColor`! If you return the value of a computed property itself from the property's getter the getter will be called again from within the getter, resulting in an infinite recursion. (See: http://stackoverflow.com/a/42334711/2062785) – Mischa Feb 20 '17 at 00:46
  • 1
    To fix this and get the expected behavior (i.e. the correct placeholder color) get the `attributedString`'s first letter (if not empty) and return its text color, otherwise `nil`. – Mischa Feb 20 '17 at 00:51
  • why are 2 colors shown in the box. I thought this was for dark mode but that wasnt the case. – asreerama Jan 23 '20 at 07:18
  • 1
    @asreerama That is the way xcode shows the transparent color. – jose920405 Feb 26 '21 at 15:33
41

In Swift 3.0, Use

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

In 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 M S
  • 1,165
  • 14
  • 16
25

This code is working in Swift3:

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

let me know if you have any issue.

Tejinder
  • 1,507
  • 19
  • 22
  • for some reason this crashes when I try to do it to more than 1 textField. The first one works fine then it crashes on all subsequent textFields. Not sure why but I wish I could use this method since its the easiest and most readable – Tommy K Jun 22 '17 at 18:08
  • There is no need to using `setValue` to access a private property. Use proper public APIs. – rmaddy Mar 14 '18 at 00:12
  • Xcode 10/Swift 5 literal syntax: `#colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)` – Lal Krishna Aug 02 '19 at 07:24
18

To set the placeholder color once for all the UITextField in your app you can do:

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

This will set the desired color for all TextField placeholders in the entire app. But it is only available since iOS 9.

There is no appearenceWhenContainedIn....() method before iOS 9 in swift but you can use one of the solutions provided here appearanceWhenContainedIn in Swift

Kuldeep
  • 4,466
  • 8
  • 32
  • 59
Krzynool
  • 319
  • 2
  • 3
8

In my case, I use Swift 4

I create extension for 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
  • 543
  • 5
  • 14
6

For Swift

Create UITextField Extension

extension UITextField{

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

If Are you set from 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
  • 2,419
  • 13
  • 26
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
  • 2,556
  • 2
  • 34
  • 56
6

Swift 4 :

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

Objective-C :

UIColor *color = [UIColor grayColor];
txtControl.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"Placeholder String..." attributes:@{NSForegroundColorAttributeName: color}];
Luckabo
  • 74
  • 5
Álvaro Agüero
  • 4,494
  • 1
  • 42
  • 39
4

Swift 3 (probably 2), you can override didSet on placeholder in UITextField subclass to apply attribute on it, this way:

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
    }
}
Kuldeep
  • 4,466
  • 8
  • 32
  • 59
ninja_iOS
  • 1,183
  • 1
  • 13
  • 20
4

Here is my quick implementation for 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 like:

streetTextField?.placeholderColor(AppColor.blueColor)

hope it helps someone!

Paul Lehn
  • 3,202
  • 1
  • 24
  • 29
  • Swift 4.2: self.attributedPlaceholder = NSAttributedString(string: placeholderText, attributes: [NSAttributedString.Key.foregroundColor : color]) – Sean Stayns Feb 15 '19 at 11:15
4

I'm surprised to see how many poor solutions there are here.

Here is a version that will always work.

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

TIP: If you change the placeholder text after setting the color- the color will reset.

David Rees
  • 6,792
  • 3
  • 31
  • 39
3

For Swift 3 and 3.1 this works perfectly fine:

passField.attributedPlaceholder = NSAttributedString(string: "password", attributes: [NSForegroundColorAttributeName: UIColor.white])
Asfand Shabbir
  • 1,234
  • 13
  • 9
3

For Swift 4.0, X-code 9.1 version or iOS 11 you can use following syntax to have different placeholder color

textField.attributedPlaceholder = NSAttributedString(string: "Placeholder Text", attributes: [NSAttributedStringKey.foregroundColor : UIColor.white])
Ashim Dahal
  • 1,097
  • 13
  • 15
3

Just write below code into Appdelegate's didFinishLaunchingWithOptions method use this if you want to change in the whole app written in Swift 4.2

UILabel.appearance(whenContainedInInstancesOf: [UITextField.self]).textColor = UIColor.white
iOS Lifee
  • 2,091
  • 23
  • 32
3

In my case, I had to make the placeholder into black color. The name of my UITextField is passwordText. Below code is tested in Swift 5 and is working fine for me. I also had an existing text for the corresponding placeholder.

let placeholderColor = UIColor.black
passwordText.attributedPlaceholder = NSAttributedString(string: passwordText.placeholder!, attributes: [NSAttributedString.Key.foregroundColor : placeholderColor])
JuvinR
  • 128
  • 1
  • 7
2

Here am i writing all UIDesignable of UITextField. With the help of this code you can directly access it from UI file Inspector in 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
  • 1,754
  • 1
  • 14
  • 26
2

Use like this in Swift,

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

In Objective C

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

crubio's answer update for Swift 4

Select the UITextField and open the identity inspector on the right:

Click on the plus button and add a new runtime attribute: placeholderLabel.textColor (instead of _placeholderLabel.textColor)

Use Color as type and select the color.

If you run your project, you will see the changes.

Dris
  • 881
  • 8
  • 19
1

For swift 4.2 and above you can do it as below:

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

In my case, I have done following:

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
  • 304
  • 1
  • 8
1
    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
  • 1,422
  • 13
  • 17
0

For Swift

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

You can use this;

self.setPlaceholderColor(textField: self.emailTextField, placeholderText: "E-Mail/Username")
Celil Bozkurt
  • 1,693
  • 16
  • 18
0

It is more about personalize your textField but anyways I'll share this code got from another page and made it a little better:

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

And you can use it like this:

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

Knowing that you have an UITextField connected to a ViewController.

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

Kuldeep
  • 4,466
  • 8
  • 32
  • 59
Andres Paladines
  • 1,142
  • 14
  • 19
0

enter image description here

For Objective 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}];

For Swift:

emailTextField.attributedPlaceholder = NSAttributedString(string: "Friend's Email",
                             attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
Mr.Javed Multani
  • 12,549
  • 4
  • 53
  • 52
0

Objective C code for changing placeholder text color.

First import this objc/runtime class -

#import <objc/runtime.h>

then replace your textfield name -

Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
UILabel *placeholderLabel = object_getIvar(YourTxtField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];
A K M Saleh Sultan
  • 2,403
  • 2
  • 22
  • 28
0

for 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
  • 1,801
  • 1
  • 14
  • 29
0

Instead of placeholder, add attributedPlaceholder on your text field:

tf.attributedPlaceholder = NSAttributedString(string: "your placeholder", attributes: [NSAttributedString.Key.foregroundColor: UIColor.yourColor])
-1

Use this for adding an attributed placeholder:

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)
Arpit Jain
  • 1,660
  • 12
  • 23
-1

For Swift 4

txtField1.attributedPlaceholder = NSAttributedString(string: "-", attributes: [NSAttributedStringKey.foregroundColor: UIColor.white])
Kuldeep
  • 4,466
  • 8
  • 32
  • 59
-2
yourTextfield.attributedPlaceholder = NSAttributedString(string: "your placeholder text",attributes: [NSForegroundColorAttributeName: UIColor.white])
DHEERAJ
  • 1,478
  • 12
  • 32