579

I'd like to change the color of the placeholder text I set in my UITextField controls, to make it black.

I'd prefer to do this without using normal text as the placeholder and having to override all the methods to imitate the behaviour of a placeholder.

I believe if I override this method:

- (void)drawPlaceholderInRect:(CGRect)rect

then I should be able to do this. But I'm unsure how to access the actual placeholder object from within this method.

Bhavin Ramani
  • 3,133
  • 5
  • 29
  • 41
adam
  • 21,709
  • 20
  • 83
  • 117

32 Answers32

814

Since the introduction of attributed strings in UIViews in iOS 6, it's possible to assign a color to the placeholder text like this:

if ([textField respondsToSelector:@selector(setAttributedPlaceholder:)]) {
  UIColor *color = [UIColor blackColor];
  textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholderText attributes:@{NSForegroundColorAttributeName: color}];
} else {
  NSLog(@"Cannot set placeholder text's color, because deployment target is earlier than iOS 6.0");
  // TODO: Add fall-back code to set placeholder color.
}
user1071136
  • 15,368
  • 2
  • 35
  • 59
  • 2
    This is good - but remember you need to set a placeholder value in IB before this will work – gheese Jan 16 '13 at 15:26
  • 4
    its also worth wrapping this in a respondsToSelector call - as without it this code will crash on pre 6.0 deployment target ( unrecognized selector sent to instance) – gheese Mar 07 '13 at 18:49
  • In order to minic the placeholder's dim color, I also used: [color colorWithAlphaComponent:0.5]; – user523234 Jun 23 '13 at 13:15
  • @einsteinx2 - I'm against wrapping this code in a check; it will just result in a broken behavior in iOS < 6.0. Meaning, you have not improved the answer, because you've not provided an "else" clause. It's incomplete either way. – user1071136 Jun 28 '13 at 02:07
  • 5
    The docs for the `attributedPlaceholder` says that is uses text attributes, except for colour. – Matt Connolly Sep 08 '13 at 21:49
  • I believe they changed the interface. I don't have old, cached versions of the doc, unfortunately, but I'm pretty sure the description was different. EDIT: apparently I'm wrong, at least according to the Wayback Machine. – user1071136 Sep 09 '13 at 23:29
  • Edited to make sure devs are aware of the fact that this answer requires iOS 6.0. – user1071136 Oct 17 '13 at 01:05
  • Great answer, works in iOS 7. This is why it's worth scrolling down :) – Aron Feb 19 '14 at 00:19
  • 1
    Any idea why it's not working for the attribute - NSFontAttributeName `[[NSAttributedString alloc] initWithString:@"placeholder" attributes: @{NSForegroundColorAttributeName: color, NSFontAttributeName : font}];` – dev4u Mar 21 '14 at 10:11
  • 3
    On iOS 7 I got this error: `[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key _field.` – i_am_jorf Apr 09 '14 at 19:27
  • Yeah, I didn't like this edit to my answer either (the part about Interface Builder). If it doesn't work, I'll remove it. – user1071136 Apr 09 '14 at 19:29
  • It didn't work for me; I'd verify before deleting. But it does feel like it depends on some internal implementation detail that may not hold forever. The `attributedPlaceholder` solution works. – i_am_jorf Apr 09 '14 at 19:37
  • The IB part didn't worked for me in IOS8 beta2, instead this key-path attribute did the job : _placeholderLabel.textColor – Macistador Jun 22 '14 at 14:10
  • @MattConnolly: My documentation still says that it uses the attributes except for the colour, which is set to 70% grey. Tried out just now, it seems that NSForegroundColorAttributeName works, and 70% grey is only used if there is no foreground color set. At least [UIColor redColor], [UIColor blackColor] and [UIColor whiteColor] worked just fine. – gnasher729 Jan 18 '16 at 15:33
  • There is a memory leak in this solution. you should be auto releasing - [[[NSAttributedString alloc] initWithString:placeholderText attributes:@{NSForegroundColorAttributeName: color}] autorelease]; – Avinash B Apr 10 '20 at 10:15
239

Easy and pain-free, could be an easy alternative for some.

_placeholderLabel.textColor

Not suggested for production, Apple may reject your submission.

Jack
  • 3,392
  • 7
  • 36
  • 61
194

You can override drawPlaceholderInRect:(CGRect)rect as such to manually render the placeholder text:

- (void) drawPlaceholderInRect:(CGRect)rect {
    [[UIColor blueColor] setFill];
    [[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:16]];
}
Kuldeep
  • 3,841
  • 6
  • 25
  • 50
adam
  • 21,709
  • 20
  • 83
  • 117
  • 45
    Something like `[self.placeholder drawInRect:rect withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment];` is probably better. That way you will respect the `textAlignment` property. I have added this to my [SSTextField](https://github.com/samsoffes/sstoolkit/blob/master/SSToolkit/SSTextField.h) class. Feel free to use in your projects. – Sam Soffes Sep 12 '11 at 18:36
  • 52
    Absolutely do NOT do what Koteg said. NEVER override methods through categories. EVER – Joshua Weinberg Nov 10 '11 at 17:17
  • 8
    @JoshuaWeinberg Is there any specific reason behind your sugestion. – Krishnan Dec 01 '11 at 14:28
  • Where should I put that method `drawPlaceholerInRect:`? – Fred Collins Dec 01 '11 at 22:38
  • 2
    It would be much better to use `self.font` rather than `[UIFont systemFontOfSize:16]` so that changing the textfields font propagates to the placeholder still. – Daniel Wood Apr 19 '12 at 09:54
  • 3
    Even better still would be to use: `[self.placeholder drawInRect:rect withFont:self.font lineBreakMode:UILineBreakModeClip alignment:self.textAlignment]` so textAlignment is propagated as well. – Daniel Wood Apr 19 '12 at 10:01
  • 5
    @Krishnan implementing a duplicate method in a category is not supported, and you can never be certain which method will be called, or if both with be called, or the order in which they will be called. – sean woodward Dec 10 '12 at 17:05
  • @MuhammadAamirALi When you subclass `UITextField`, it's the NSString instance variable `placeholder` of your class's superclass (UITextField). See more [here](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextField_Class/Reference/UITextField.html#//apple_ref/occ/instp/UITextField/placeholder) – Tom Redman Aug 12 '13 at 20:38
  • 8
    In iOS7 you can alter the rect by using CGRectInset(rect, 0, (rect.size.height - self.font.lineHeight) / 2.0) to vertically center the text. – Brian S Oct 01 '13 at 01:55
172

You can Change the Placeholder textcolor to any color which you want by using the below code.

UIColor *color = [UIColor lightTextColor];
YOURTEXTFIELD.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"PlaceHolder Text" attributes:@{NSForegroundColorAttributeName: color}];
Manju
  • 4,083
  • 2
  • 16
  • 12
168

This works in Swift <3.0:

myTextField.attributedPlaceholder = 
NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName : UIColor.redColor()])

Tested in iOS 8.2 and iOS 8.3 beta 4.

Swift 3:

myTextfield.attributedPlaceholder =
NSAttributedString(string: "placeholder text", attributes: [NSForegroundColorAttributeName : UIColor.red])

Swift 4:

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

Swift 4.2:

myTextfield.attributedPlaceholder =
NSAttributedString(string: "placeholder text", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])
ekscrypto
  • 3,509
  • 1
  • 20
  • 36
Tomino
  • 5,050
  • 6
  • 32
  • 47
158

Maybe you want to try this way, but Apple might warn you about accessing private ivar:

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

NOTE
This is not working on iOS 7 anymore, according to Martin Alléus.

digdog
  • 4,170
  • 1
  • 24
  • 23
  • anybody knows if this gets through the review? – dlinsin Mar 07 '10 at 09:18
  • any body please tell me if we use above code will it reject by apple – Srinivas Oct 20 '11 at 07:12
  • 6
    I use this method in my app. The review was OK. So I think it's fine to use it. – Michael A. May 08 '12 at 09:00
  • This is an old post, but just to add my 2 cents: [self.myTextField setTextColor:[UIColor darkGrayColor]]; – imcc May 23 '12 at 00:14
  • 1
    @colorblue That would set the text color while the question is about placeholder text color. – Chintan Patel Aug 27 '12 at 05:22
  • Looks like it won't get rejected, but I don't think this will be guaranteed to work with all iOS versions, especially going forward. Using anything undocumented is fair game for Apple to change and thus break your app. – Jared Egan Aug 30 '12 at 21:50
  • 9
    This is not app store safe and should _not_ be encouraged, you're not guaranteed to get approved or stay in approved with these techniques. – Sveinung Kval Bakken Dec 17 '12 at 13:37
  • 32
    It shouldn't really matter if it's approved or not really. The important thing is that this could break your app in future OS updates. – pablasso Jan 29 '13 at 00:01
  • Heads up: This crashes in iOS 7 – alleus Sep 06 '13 at 14:43
  • 2
    Not having any problem with iOS 7... I gave it a try despite the note and it seems to work fine and I've used this approach in the past with no problems. – WCByrne Oct 16 '13 at 16:54
  • There is no problem in iOS 7 - plus some documented features have already broken no matter what. It's Apple's game ... we just have to catch on. – Michael Chourdakis Dec 11 '13 at 18:18
  • I would definitely put a `@try @catch` block around this. I cringe by the idea what would happen to your app if Apple decides to remove the `_placeholderLabel` iVar and you don't properly handle the exception ^^ – Hless Feb 25 '14 at 15:11
  • iOS 8.2, it causes an exception – RodolfoAntonici Jun 21 '16 at 16:45
  • 6
    This was always a bad idea, and now it's broken on iOS 13: `Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug` – Ryder Mackay Jul 03 '19 at 03:32
82

Swift 3.0 + Storyboard

In order to change placeholder color in storyboard, create an extension with next code. (feel free to update this code, if you think, it can be clearer and safer).

extension UITextField {
    @IBInspectable var placeholderColor: UIColor {
        get {
            guard let currentAttributedPlaceholderColor = attributedPlaceholder?.attribute(NSForegroundColorAttributeName, at: 0, effectiveRange: nil) as? UIColor else { return UIColor.clear }
            return currentAttributedPlaceholderColor
        }
        set {
            guard let currentAttributedString = attributedPlaceholder else { return }
            let attributes = [NSForegroundColorAttributeName : newValue]

            attributedPlaceholder = NSAttributedString(string: currentAttributedString.string, attributes: attributes)
        }
    }
}

enter image description here

Swift 4 version

extension UITextField {
    @IBInspectable var placeholderColor: UIColor {
        get {
            return attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor ?? .clear
        }
        set {
            guard let attributedPlaceholder = attributedPlaceholder else { return }
            let attributes: [NSAttributedStringKey: UIColor] = [.foregroundColor: newValue]
            self.attributedPlaceholder = NSAttributedString(string: attributedPlaceholder.string, attributes: attributes)
        }
    }
}

Swift 5 version

extension UITextField {
    @IBInspectable var placeholderColor: UIColor {
        get {
            return attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor ?? .clear
        }
        set {
            guard let attributedPlaceholder = attributedPlaceholder else { return }
            let attributes: [NSAttributedString.Key: UIColor] = [.foregroundColor: newValue]
            self.attributedPlaceholder = NSAttributedString(string: attributedPlaceholder.string, attributes: attributes)
        }
    }
}
DZoki019
  • 321
  • 2
  • 11
Nik Kov
  • 10,605
  • 4
  • 56
  • 96
76

In Swift:

if let placeholder = yourTextField.placeholder {
    yourTextField.attributedPlaceholder = NSAttributedString(string:placeholder, 
        attributes: [NSForegroundColorAttributeName: UIColor.blackColor()])
}

In Swift 4.0:

if let placeholder = yourTextField.placeholder {
    yourTextField.attributedPlaceholder = NSAttributedString(string:placeholder, 
        attributes: [NSAttributedStringKey.foregroundColor: UIColor.black])
}
clemens
  • 14,173
  • 11
  • 38
  • 52
Beninho85
  • 2,977
  • 23
  • 21
  • If you didn't set the placeholder text before calling that it will crash the app – apinho Feb 05 '16 at 14:32
  • This is the best one, thank you. @apinho nothing will crash here – Markus Sep 28 '17 at 15:31
  • //In Swift 4 if let placeholder = yourTextField.placeholder { yourTextField.attributedPlaceholder = NSAttributedString(string:placeholder, attributes: [NSAttributedStringKey.foregroundColor: UIColor.white]) } – Ronaldo Albertini Oct 25 '17 at 20:15
  • Beware that changing the placeholder text value after this code has been executed will bring back the default placeholder color. – Alessandro Vendruscolo Dec 27 '17 at 15:09
43

The following only with iOS6+ (as indicated in Alexander W's comment):

UIColor *color = [UIColor grayColor];
nameText.attributedPlaceholder =
   [[NSAttributedString alloc]
       initWithString:@"Full Name"
       attributes:@{NSForegroundColorAttributeName:color}];
Fattie
  • 30,632
  • 54
  • 336
  • 607
Gaurav Gilani
  • 1,586
  • 14
  • 18
34

I had already faced this issue. In my case below code is correct.

Objective C

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

For Swift 4.X

tf_mobile.setValue(UIColor.white, forKeyPath: "_placeholderLabel.textColor")

For iOS 13 Swift Code

tf_mobile.attributedPlaceholder = NSAttributedString(string:"PlaceHolder Text", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])

You can also use below code for iOS 13

let iVar = class_getInstanceVariable(UITextField.self, "_placeholderLabel")!
let placeholderLabel = object_getIvar(tf_mobile, iVar) as! UILabel
placeholderLabel.textColor = .red

Hope, this may help you.

Ashu
  • 2,867
  • 29
  • 30
  • @Ashu this causes crash in ios 13 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug' it wont be even build I am not talking about placing into AppStore – Melany Oct 08 '19 at 10:55
  • 1
    IOS 13 this was restricted can't use this anymore – Kishore Kumar Oct 30 '19 at 05:48
  • 1
    @Mehdico I updated the answer for iOS 13. Hope this will helps you. – Ashu Nov 28 '19 at 05:34
  • Took me far too long to learn that I had to make this change in `viewWillAppear` or `viewDidAppear`. `viewDidLoad` is too early. – Four Mar 10 '20 at 00:38
  • I had to use `UIColor(displayP3Red: 255, green: 255, blue: 255, alpha: 0.3)` constructor for UIColor instead of `UIColor(red: 255, green: 255, blue: 255, alpha: 0.3)` – AppreciateIt Apr 01 '20 at 23:57
32

With this we can change the color of textfield's placeholder text in iOS

[self.userNameTxt setValue:[UIColor colorWithRed:41.0/255.0 green:91.0/255.0 blue:106.0/255.0 alpha:1.0] forKeyPath:@"_placeholderLabel.textColor"];
Yogi
  • 3,528
  • 3
  • 32
  • 51
Uma Madhavi
  • 4,601
  • 5
  • 34
  • 70
  • @Teddy how did you do it now? I started to have problems with this. – Jalil Oct 04 '19 at 17:51
  • @Jalil I hope I am still on time for you. textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"text" attributes:@{NSForegroundColorAttributeName:[UIColor colorWithHexString:@"ffffff55"]}]; – Teddy Oct 06 '19 at 19:19
21

in swift 3.X

textField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes:[NSForegroundColorAttributeName: UIColor.black])

in swift 5

textField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes: [NSAttributedString.Key.foregroundColor : UIColor.black])
Josh Wolff
  • 1,451
  • 1
  • 12
  • 32
MAhipal Singh
  • 4,220
  • 35
  • 53
19

Why don't you just use UIAppearance method:

[[UILabel appearanceWhenContainedIn:[UITextField class], nil] setTextColor:[UIColor whateverColorYouNeed]];
Matthias
  • 3,486
  • 2
  • 29
  • 38
Valerii Lider
  • 1,694
  • 16
  • 21
18

Also in your storyboard, without single line of code

enter image description here

Petr Syrov
  • 12,923
  • 3
  • 17
  • 29
  • 1
    How come you know this? It is best approach i think but how one can know this? Please tell i am new to ios programming. – Yawar Apr 29 '16 at 12:44
  • 2
    It's very universal. Once you know it use it everywhere ;) – Petr Syrov Apr 29 '16 at 14:01
  • I know once I understand whats running behind it i am going to use it a lot. But I mean "_placeholderLabel.textColor" this should be a child view of textfield. Is there a way to see this type of information about a control? – Yawar Apr 30 '16 at 06:11
  • 2
    @Yawar You can use the view hierarchy inspector in Xcode, or introspect the view in the debugger. – David Ganster Jun 02 '16 at 14:22
  • good one, regardless of textfield, you can use the same 'tile/name' for keypath – Naishta Jul 05 '17 at 16:25
12

For iOS 6.0 +

[textfield setValue:your_color forKeyPath:@"_placeholderLabel.textColor"];

Hope it helps.

Note: Apple may reject (0.01% chances) your app as we are accessing private API. I am using this in all my projects since two years, but Apple didn't ask for this.

Fahim Parkar
  • 28,922
  • 40
  • 153
  • 260
10

For Xamarin.iOS developers, I found it from this document https://developer.xamarin.com/api/type/Foundation.NSAttributedString/

textField.AttributedPlaceholder = new NSAttributedString ("Hello, world",new UIStringAttributes () { ForegroundColor =  UIColor.Red });
ManuQiao
  • 650
  • 7
  • 19
  • Thank you !! I was first using CTStringAttributes and not UIStringAttributes and couldn't figure it out. Be careful to not use this : `new NSAttributedString("placeholderstring", new CTStringAttributes() { ForegroundColor = UIColor.Blue.CGColor });` – Yohan Dahmani Jun 07 '17 at 08:08
9

Swift version. Probably it would help someone.

class TextField: UITextField {
   override var placeholder: String? {
        didSet {
            let placeholderString = NSAttributedString(string: placeholder!, attributes: [NSForegroundColorAttributeName: UIColor.whiteColor()])
            self.attributedPlaceholder = placeholderString
        }
    }
}
Machado
  • 12,805
  • 13
  • 46
  • 87
Max Tymchii
  • 717
  • 7
  • 15
8

iOS 6 and later offers attributedPlaceholder on UITextField. iOS 3.2 and later offers setAttributes:range: on NSMutableAttributedString.

You can do the following:

NSMutableAttributedString *ms = [[NSMutableAttributedString alloc] initWithString:self.yourInput.placeholder];
UIFont *placeholderFont = self.yourInput.font;
NSRange fullRange = NSMakeRange(0, ms.length);
NSDictionary *newProps = @{NSForegroundColorAttributeName:[UIColor yourColor], NSFontAttributeName:placeholderFont};
[ms setAttributes:newProps range:fullRange];
self.yourInput.attributedPlaceholder = ms;
Kuldeep
  • 3,841
  • 6
  • 25
  • 50
William Power
  • 666
  • 7
  • 12
  • Not sure what is causing the problem, this code i have called in viewdidLoad. new color and font size appears only after redraw. any thing else needs to be done along with this? – Vinayaka Karjigi Oct 02 '13 at 05:17
  • it got solved, i forgot to set font for UITextfield before using that font for placeholder text. my bad – Vinayaka Karjigi Oct 02 '13 at 05:21
7

This solution for Swift 4.1

    textName.attributedPlaceholder = NSAttributedString(string: textName.placeholder!, attributes: [NSAttributedStringKey.foregroundColor : UIColor.red])
Mantosh Kumar
  • 255
  • 3
  • 8
6

To handle both vertical and horizontal alignment as well as color of placeholder in iOS7. drawInRect and drawAtPoint no longer use current context fillColor.

https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html

Obj-C

@interface CustomPlaceHolderTextColorTextField : UITextField

@end


@implementation CustomPlaceHolderTextColorTextField : UITextField


-(void) drawPlaceholderInRect:(CGRect)rect  {
    if (self.placeholder) {
        // color of placeholder text
        UIColor *placeHolderTextColor = [UIColor redColor];

        CGSize drawSize = [self.placeholder sizeWithAttributes:[NSDictionary dictionaryWithObject:self.font forKey:NSFontAttributeName]];
        CGRect drawRect = rect;

        // verticially align text
        drawRect.origin.y = (rect.size.height - drawSize.height) * 0.5;

        // set alignment
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.alignment = self.textAlignment;

        // dictionary of attributes, font, paragraphstyle, and color
        NSDictionary *drawAttributes = @{NSFontAttributeName: self.font,
                                     NSParagraphStyleAttributeName : paragraphStyle,
                                     NSForegroundColorAttributeName : placeHolderTextColor};


        // draw
        [self.placeholder drawInRect:drawRect withAttributes:drawAttributes];
    }
}

@end
Kuldeep
  • 3,841
  • 6
  • 25
  • 50
aumansoftware
  • 835
  • 8
  • 6
  • Thanks for this excellent solution-- which properly centers text vertically (useful with custom fonts). The only thing I would add is that this solution is not compatible with iOS 6 or older (easy enough to fix by falling back on [self.placeholder drawInRect:rect withFont:self.font lineBreakMode:NSLineBreakByTruncatingTail alignment:self.textAlignment]; – lifjoy Jul 02 '14 at 23:48
6

Categories FTW. Could be optimized to check for effective color change.


#import <UIKit/UIKit.h>

@interface UITextField (OPConvenience)

@property (strong, nonatomic) UIColor* placeholderColor;

@end

#import "UITextField+OPConvenience.h"

@implementation UITextField (OPConvenience)

- (void) setPlaceholderColor: (UIColor*) color {
    if (color) {
        NSMutableAttributedString* attrString = [self.attributedPlaceholder mutableCopy];
        [attrString setAttributes: @{NSForegroundColorAttributeName: color} range: NSMakeRange(0,  attrString.length)];
        self.attributedPlaceholder =  attrString;
    }
}

- (UIColor*) placeholderColor {
    return [self.attributedPlaceholder attribute: NSForegroundColorAttributeName atIndex: 0 effectiveRange: NULL];
}

@end
osxdirk
  • 548
  • 6
  • 11
6

Swift 5 WITH CAVEAT.

let attributes = [ NSAttributedString.Key.foregroundColor: UIColor.someColor ]
let placeHolderString = NSAttributedString(string: "DON'T_DELETE", attributes: attributes)
txtField.attributedPlaceholder = placeHolderString

The caveat being that you MUST enter a non-empty String where "DON'T_DELETE" is, even if that string is set in code elsewhere. Might save you five minutes of head-sctratching.

HenryRootTwo
  • 2,419
  • 1
  • 22
  • 26
4

Overriding drawPlaceholderInRect: would be the correct way, but it does not work due to a bug in the API (or the documentation).

The method never gets called on an UITextField.

See also drawTextInRect on UITextField not called

You might use digdog's solution. As I am not sure if that gets past Apples review, I chose a different solution: Overlay the text field with my own label which imitates the placeholder behaviour.

This is a bit messy though. The code looks like this (Note I am doing this inside a subclass of TextField):

@implementation PlaceholderChangingTextField

- (void) changePlaceholderColor:(UIColor*)color
{    
    // Need to place the overlay placeholder exactly above the original placeholder
    UILabel *overlayPlaceholderLabel = [[[UILabel alloc] initWithFrame:CGRectMake(self.frame.origin.x + 8, self.frame.origin.y + 4, self.frame.size.width - 16, self.frame.size.height - 8)] autorelease];
    overlayPlaceholderLabel.backgroundColor = [UIColor whiteColor];
    overlayPlaceholderLabel.opaque = YES;
    overlayPlaceholderLabel.text = self.placeholder;
    overlayPlaceholderLabel.textColor = color;
    overlayPlaceholderLabel.font = self.font;
    // Need to add it to the superview, as otherwise we cannot overlay the buildin text label.
    [self.superview addSubview:overlayPlaceholderLabel];
    self.placeholder = nil;
}
Community
  • 1
  • 1
henning77
  • 3,774
  • 2
  • 24
  • 32
  • how would you feel about sharing your review-friendly solution? – adam Apr 06 '10 at 10:18
  • I added the solution I used. I had to do a bit of digging, as this was some time ago :) – henning77 May 02 '10 at 09:25
  • I did something similar to this, but I placed the code in a category, and needed to do a check in shouldChangeCharacters on whether to make it visible, which was a second method in the category called - (void) overlayPlaceholderVisible : (BOOL) visible; – David van Dugteren Jan 29 '13 at 00:13
3

Iam new to xcode and i found a way around to the same effect.

I placed a uilabel in place of place holder with the desired format and hide it in

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    switch (textField.tag)
    {
        case 0:
            lblUserName.hidden=YES;
            break;

        case 1:
            lblPassword.hidden=YES;
            break;
 
        default:
            break;
    }
}

I agree its a work around and not a real solution but the effect was same got it from this link

NOTE: Still works on iOS 7 :|

Community
  • 1
  • 1
amar
  • 4,147
  • 6
  • 35
  • 48
2

For those using Monotouch (Xamarin.iOS), here's Adam's answer, translated to C#:

public class MyTextBox : UITextField
{
    public override void DrawPlaceholder(RectangleF rect)
    {
        UIColor.FromWhiteAlpha(0.5f, 1f).SetFill();
        new NSString(this.Placeholder).DrawString(rect, Font);
    }
}
Wolfgang Schreurs
  • 11,649
  • 7
  • 47
  • 89
Diego
  • 16,895
  • 5
  • 56
  • 64
  • Great. This was not really obvious, you probably saved me some time :) I did edit your solution though, since I think it's a better idea to use the font set in the `Font` property of the text field. – Wolfgang Schreurs Dec 06 '13 at 20:55
2

The best i can do for both iOS7 and less is:

- (CGRect)placeholderRectForBounds:(CGRect)bounds {
  return [self textRectForBounds:bounds];
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
  return [self textRectForBounds:bounds];
}

- (CGRect)textRectForBounds:(CGRect)bounds {
  CGRect rect = CGRectInset(bounds, 0, 6); //TODO: can be improved by comparing font size versus bounds.size.height
  return rect;
}

- (void)drawPlaceholderInRect:(CGRect)rect {
  UIColor *color =RGBColor(65, 65, 65);
  if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    [self.placeholder drawInRect:rect withAttributes:@{NSFontAttributeName:self.font, UITextAttributeTextColor:color}];
  } else {
    [color setFill];
    [self.placeholder drawInRect:rect withFont:self.font];
  }
}
Aleksei Minaev
  • 1,219
  • 15
  • 15
1

I needed to keep the placeholder alignment so adam's answer was not enough for me.

To solve this I used a small variation that I hope will help some of you too:

- (void) drawPlaceholderInRect:(CGRect)rect {
    //search field placeholder color
    UIColor* color = [UIColor whiteColor];

    [color setFill];
    [self.placeholder drawInRect:rect withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment];
}
Tomer Even
  • 4,366
  • 2
  • 26
  • 36
1
[txt_field setValue:ColorFromHEX(@"#525252") forKeyPath:@"_placeholderLabel.textColor"];
MaxEcho
  • 13,325
  • 6
  • 72
  • 84
Mubin Shaikh
  • 376
  • 4
  • 9
  • A little hint on this is that you are accessing a private iVar (_placeholderLabel) and in the past Apple has been a little fincky about doing that. :) – Alexander W Nov 04 '14 at 12:18
1

For set Attributed Textfield Placeholder with Multiple color ,

Just specify the Text ,

  //txtServiceText is your Textfield
 _txtServiceText.placeholder=@"Badal/ Shah";
    NSMutableAttributedString *mutable = [[NSMutableAttributedString alloc] initWithString:_txtServiceText.placeholder];
     [mutable addAttribute: NSForegroundColorAttributeName value:[UIColor whiteColor] range:[_txtServiceText.placeholder rangeOfString:@"Badal/"]]; //Replace it with your first color Text
    [mutable addAttribute: NSForegroundColorAttributeName value:[UIColor orangeColor] range:[_txtServiceText.placeholder rangeOfString:@"Shah"]]; // Replace it with your secondcolor string.
    _txtServiceText.attributedPlaceholder=mutable;

Output :-

enter image description here

Badal Shah
  • 7,255
  • 2
  • 27
  • 59
0

Another option that doesn't require subclassing - leave placeholder blank, and put a label on top of edit button. Manage the label just like you would manage the placeholder (clearing once user inputs anything..)

kolinko
  • 1,603
  • 1
  • 14
  • 31
  • I think that this would be efficient if you have one textfield, but if you're trying to make this change on a more global scale this solution would add a considerable amount of overhead to your project. – James Parker Jul 09 '14 at 13:03
0

In Swift 3

import UIKit

let TEXTFIELD_BLUE  = UIColor.blue
let TEXTFIELD_GRAY  = UIColor.gray

class DBTextField: UITextField {
    /// Tetxfield Placeholder Color
    @IBInspectable var palceHolderColor: UIColor = TEXTFIELD_GRAY
    func setupTextField () {
        self.attributedPlaceholder = NSAttributedString(string:self.placeholder != nil ? self.placeholder! : "",
                                                            attributes:[NSForegroundColorAttributeName: palceHolderColor])
    }
}

class DBLocalizedTextField : UITextField {
    override func awakeFromNib() {
        super.awakeFromNib()
        self.placeholder = self.placeholder
    }
}
Kuldeep
  • 3,841
  • 6
  • 25
  • 50
Amul4608
  • 1,232
  • 12
  • 25
-10

I would suggest another solution. Since the placeholder text uses the default font settings of the textfield, just set the initial font color to the placeholder font color you want. Then set the delegate of your UITextField and implement the following methods:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    //set color for text input
    textField.textColor = [UIColor blackColor];
    return YES;
}

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    //set color for placeholder text
    textField.textColor = [UIColor redColor];
    return YES;
}

So, if a user starts typing in the textfield the color of the text changes to black and after the textfield gets cleared again the placeholder text will appear in red color again.

Cheers, anka

anka
  • 3,639
  • 1
  • 26
  • 35