20

I have seen some answers that show how to change the placeHolder text color for UITextField by overriding the drawPlaceholderInRect: method such as this one:

iPhone UITextField - Change placeholder text color

but that does not maintain the existing attributes such as alignment, font, etc...what is a better way to solve this?

Community
  • 1
  • 1
Ed Fernandez
  • 1,823
  • 2
  • 14
  • 18

4 Answers4

36

From iOS 6,

Without any subclassing, one can accomplish this with a couple lines of code like so:

UIColor *color = [UIColor blackColor];
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholderText attributes:@{NSForegroundColorAttributeName: color}];
Hemang
  • 26,840
  • 19
  • 119
  • 186
Forrest
  • 620
  • 1
  • 6
  • 13
  • 1
    This is not a complete solution because it don't persevere the existing attributes. The chosen answer below solves for preserving the attributes while changing the placeholder text and not wiping out any other attribtues. – Ed Fernandez Jun 08 '14 at 06:02
22

There are multiple ways to achieve this.

Using Interface Builder or Storyboard

  • Select the Textfield for which you want to change placeholder color
  • go to the Identity inspector menu on Top right of Xcode
  • Add the key value pair this way

Key path = _placeholderLabel.textColor

Click the Type and chose Color attribute .

Then select the color in value.

enter image description here

Set The placeholder color using code :

Process 1:

[textField setValue:[UIColor blueColor] forKeyPath:@"_placeholderLabel.textColor"];

Process 2 :

Override drawPlaceholderInRect:(CGRect)rect method

- (void) drawPlaceholderInRect:(CGRect)rect {
    [[UIColor blueColor] setFill];
    [[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:14]];
}
ABS
  • 7,634
  • 1
  • 21
  • 20
  • Dude, thanks a lot! I spent a few hours trying to figure this out, but I wasn't able to solve it until I came across your post... thanks! – bluefox Dec 01 '17 at 14:31
  • If you used _placeholderLabel, you will get this crash Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug – Hosny Dec 16 '19 at 19:12
15

There is indeed a much better way to handle this now. This will work for iOS 6 and 7.

(Note this example, I created the code in AwakeFromNib since it won't be changing colors once set. But if you don't use XIB, you will have to change the location where you put this code, such as in drawPlaceholderInRect,)

In this example, we create a subclass of UITextField, override awakeFromNib and then set the placeHolder text color to red:

- (void)awakeFromNib
{
    if ([self.attributedPlaceholder length])
    {
        // Extract attributes
        NSDictionary * attributes = (NSMutableDictionary *)[ (NSAttributedString *)self.attributedPlaceholder attributesAtIndex:0 effectiveRange:NULL];

        NSMutableDictionary * newAttributes = [[NSMutableDictionary alloc] initWithDictionary:attributes];

        [newAttributes setObject:[UIColor redColor] forKey:NSForegroundColorAttributeName];

        // Set new text with extracted attributes
        self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:[self.attributedPlaceholder string] attributes:newAttributes];

    }
}

The nice thing about this approach is that it maintains the current UITextField properties for the placeHolder string and so will allow you to work in IB for most of what you set. In addition, its much more efficient than doing everytime you need to draw. It also allows you to change any other property you want on the placeHolder text while maintaining the rest of the properties.

As mentioned above, if don't use XIBs, then you will need to call this at some other time. If you do put this code in the drawPlaceholderInRect: method, then make sure you call [super drawPlaceholderInRect:] at the end of it.

Ed Fernandez
  • 1,823
  • 2
  • 14
  • 18
  • You can use `drawPlaceholderInRect:`. Just update the line to: `[[self placeholder] drawInRect:rect withFont:self.font lineBreakMode:NSLineBreakByClipping alignment:self.textAlignment];`. This keeps the font and alignment. – rmaddy Sep 03 '13 at 05:39
  • That would seem to imply that you know what the linebreakMode is? Regardless, you are better off just using my solution above even if you use it inside the drawPlaceHolderInRect call. – Ed Fernandez Sep 11 '13 at 06:58
  • tanks , it well worked i used it as category class instead of subclass – Shabeer Ali Nov 23 '16 at 17:34
3

The safe way to customize UITextField’s placeholder is subclassing the UITextField and overriding placeholderRectForBounds:, Apple won’t bother you on this one. However, if you want to take the risk, you can try this way:

[self.MyTextField setValue:[UIColor darkGrayColor] forKeyPath:@"_placeholderLabel.textColor"];

Source.

Nazik
  • 8,696
  • 27
  • 77
  • 123
  • This defeats the whole purpose of the original question, which is to presever all the existing text attributes, but just change the color. – Ed Fernandez Sep 03 '13 at 05:39