iPhone UITextField - Change placeholder text color
Asked Answered
H

32

598

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.

Hague answered 27/8, 2009 at 10:36 Comment(0)
H
197

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]];
}
Hague answered 3/8, 2010 at 11:35 Comment(9)
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 class. Feel free to use in your projects.Sunny
Absolutely do NOT do what Koteg said. NEVER override methods through categories. EVERHydrosol
@JoshuaWeinberg Is there any specific reason behind your sugestion.Scriber
Where should I put that method drawPlaceholerInRect:?Fern
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.Llanes
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.Llanes
@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.Hamner
@MuhammadAamirALi When you subclass UITextField, it's the NSString instance variable placeholder of your class's superclass (UITextField). See more hereRossiter
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.Sebastien
L
817

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.
}
Lesbos answered 4/12, 2012 at 3:8 Comment(16)
This is good - but remember you need to set a placeholder value in IB before this will workLooksee
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)Looksee
In order to minic the placeholder's dim color, I also used: [color colorWithAlphaComponent:0.5];Tomtom
@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.Lesbos
The docs for the attributedPlaceholder says that is uses text attributes, except for colour.Buchbinder
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.Lesbos
Edited to make sure devs are aware of the fact that this answer requires iOS 6.0.Lesbos
Great answer, works in iOS 7. This is why it's worth scrolling down :)Igal
Any idea why it's not working for the attribute - NSFontAttributeName [[NSAttributedString alloc] initWithString:@"placeholder" attributes: @{NSForegroundColorAttributeName: color, NSFontAttributeName : font}];Byler
On iOS 7 I got this error: [<UITextField 0x11561d90> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _field.Camillacamille
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.Lesbos
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.Camillacamille
The IB part didn't worked for me in IOS8 beta2, instead this key-path attribute did the job : _placeholderLabel.textColorObie
@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.Approachable
There is a memory leak in this solution. you should be auto releasing - [[[NSAttributedString alloc] initWithString:placeholderText attributes:@{NSForegroundColorAttributeName: color}] autorelease];Dryclean
Working in ios 15 / 2022Horacehoracio
O
239

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

_placeholderLabel.textColor

Not suggested for production, Apple may reject your submission.

Obannon answered 25/2, 2014 at 14:28 Comment(11)
Are you using this in production? I mean to access a private property.Dentelle
Not sure if it works in production but it is a great solution. Thanks :)Aardwolf
Working fine on IOS 7.0 thanks for the best solutions.Sward
Maybe add the text to your answer for fast copy and paste. _placeholderLabel.textColorPharyngo
Working fine on iOS 8.4Allelomorph
Don't use this method, i have used this and itune store, has rejected my application.Turnpike
@dreamBegin he was likely rejected for an unrelated reason. There's no reason Apple would reject an app because of this.Subheading
@Asadali you must be having other reason, i don't think so at one side apple is providing such feature to customise things and at other side they will reject it. Working fine for me.Saucedo
i've used this in many, many apps and never had a single rejection ... for this reason, anyway :)Scudder
I think any kind of private library method should NEVER be recommended as solution to anythingPhan
@Subheading _placeholderLabel is a private property. This solution is subject to being rejected for use of private API.Surround
H
197

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]];
}
Hague answered 3/8, 2010 at 11:35 Comment(9)
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 class. Feel free to use in your projects.Sunny
Absolutely do NOT do what Koteg said. NEVER override methods through categories. EVERHydrosol
@JoshuaWeinberg Is there any specific reason behind your sugestion.Scriber
Where should I put that method drawPlaceholerInRect:?Fern
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.Llanes
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.Llanes
@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.Hamner
@MuhammadAamirALi When you subclass UITextField, it's the NSString instance variable placeholder of your class's superclass (UITextField). See more hereRossiter
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.Sebastien
S
183

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])
Sweltering answered 6/1, 2015 at 11:50 Comment(1)
Using your solution on iOS8.2, works like a charm. Perfect solution here. Using in objective C also.Colp
K
175

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}];
Klayman answered 8/11, 2013 at 6:18 Comment(8)
Best answer suggested. Works, and uses documented APIs.Clary
How do you make this work for UISearchBar? There is no attributedPlaceholder property.Waistline
This answer is not correct – according to the docs, the text color information of attributedPlaceholder is ignored developer.apple.com/library/ios/documentation/UIKit/Reference/…Hellespont
Thanks everyone. Hope it was of some help. Adlai Holler give it a try bro!!! This answer was for the previous version of iOS. If you have better answer we are open to suggestions.Klayman
Doesn't work on iOS8 as there's no attributedPlaceholder propertyCollectanea
this is same as selected answer and doesn't work for iOS7+Cognizant
Works very well on iOS 11Noon
Works in iOS 12Oren
E
157

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.

Endomorphic answered 4/1, 2010 at 7:53 Comment(15)
anybody knows if this gets through the review?Transeunt
any body please tell me if we use above code will it reject by appleWiley
I use this method in my app. The review was OK. So I think it's fine to use it.Changchangaris
This is an old post, but just to add my 2 cents: [self.myTextField setTextColor:[UIColor darkGrayColor]];Usm
@colorblue That would set the text color while the question is about placeholder text color.Bouffard
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.Jitney
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.Charolettecharon
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.Alberthaalberti
Heads up: This crashes in iOS 7Unexpected
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.Speculative
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.Alius
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 ^^Hand
iOS 8.2, it causes an exceptionSlaveholder
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 😈Bengurion
you use private api. Of course it may not work or cause unpredictable problemExclude
C
96

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)
        }
    }
}
Calore answered 21/5, 2017 at 12:5 Comment(2)
The compiler can't find out NSAttributedStringKey.Conchoidal
Works in iOS 13Tallulah
D
78

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])
}
Dice answered 11/12, 2014 at 16:22 Comment(4)
If you didn't set the placeholder text before calling that it will crash the appInfestation
This is the best one, thank you. @Infestation nothing will crash hereBruell
//In Swift 4 if let placeholder = yourTextField.placeholder { yourTextField.attributedPlaceholder = NSAttributedString(string:placeholder, attributes: [NSAttributedStringKey.foregroundColor: UIColor.white]) }Ileac
Beware that changing the placeholder text value after this code has been executed will bring back the default placeholder color.Copulate
D
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}];
Designing answered 19/5, 2014 at 6:33 Comment(0)
L
36

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.

Librium answered 20/6, 2015 at 13:20 Comment(6)
@Librium 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 AppStoreEer
IOS 13 this was restricted can't use this anymoreRoyalty
@Mehdico I updated the answer for iOS 13. Hope this will helps you.Librium
Took me far too long to learn that I had to make this change in viewWillAppear or viewDidAppear. viewDidLoad is too early.Tangle
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)Deimos
placeholderLabel use this attribute if getting crash.Dogear
S
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"];
Sheet answered 12/2, 2016 at 7:30 Comment(2)
@Teddy how did you do it now? I started to have problems with this.Tallulah
@Tallulah I hope I am still on time for you. textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"text" attributes:@{NSForegroundColorAttributeName:[UIColor colorWithHexString:@"ffffff55"]}];Yellowish
C
29

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])
Courtund answered 1/1, 2018 at 6:25 Comment(0)
G
22

Why don't you just use UIAppearance method:

[[UILabel appearanceWhenContainedIn:[UITextField class], nil] setTextColor:[UIColor whateverColorYouNeed]];
Gabo answered 19/12, 2013 at 13:8 Comment(2)
Works great! Color of text doesn't affected (At least with different proxy for textColor property)Prolonge
Great worked but showing warning for this methodPhotographic
U
18

Also in your storyboard, without single line of code

enter image description here

Unjust answered 5/2, 2016 at 10:0 Comment(5)
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.Hessite
It's very universal. Once you know it use it everywhere ;)Unjust
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?Hessite
@Hessite You can use the view hierarchy inspector in Xcode, or introspect the view in the debugger.Napery
good one, regardless of textfield, you can use the same 'tile/name' for keypathSpinelli
D
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.

Dryden answered 30/12, 2014 at 6:48 Comment(1)
throws a terminating with uncaught exception of type NSException for iOS8Cognizant
A
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 });
Asdic answered 7/12, 2016 at 11:59 Comment(1)
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 });Godesberg
P
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
        }
    }
}
Papagena answered 29/8, 2016 at 10:5 Comment(0)
H
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;
Harpole answered 2/10, 2013 at 1:21 Comment(2)
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?Wheelock
it got solved, i forgot to set font for UITextfield before using that font for placeholder text. my badWheelock
V
7

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
Victim answered 2/11, 2013 at 15:22 Comment(1)
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];Cadmar
B
7

This solution for Swift 4.1

    textName.attributedPlaceholder = NSAttributedString(string: textName.placeholder!, attributes: [NSAttributedStringKey.foregroundColor : UIColor.red])
Bozovich answered 10/10, 2018 at 9:54 Comment(0)
V
7

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.

  • if subclassing you MUST do it in layoutSubviews (not in init)

  • strangely you do NOT have to clear the normal placeholder. it knows to not draw placeholder if you're using the attributed placeholder.

Vivienne answered 31/10, 2019 at 2:0 Comment(0)
P
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
Potable answered 27/5, 2014 at 20:35 Comment(0)
F
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;
}
Figge answered 6/4, 2010 at 0:3 Comment(3)
how would you feel about sharing your review-friendly solution?Hague
I added the solution I used. I had to do a bit of digging, as this was some time ago :)Figge
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;Protozoan
C
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 :|

Cinderellacindi answered 23/5, 2012 at 9:14 Comment(0)
Y
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);
    }
}
Yasukoyataghan answered 18/9, 2013 at 17:15 Comment(1)
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.Enterostomy
B
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];
  }
}
Boatswain answered 25/9, 2013 at 7:2 Comment(0)
C
2

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

Cervical answered 20/5, 2016 at 5:52 Comment(0)
L
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];
}
Lamrert answered 10/6, 2013 at 10:13 Comment(1)
UILineBreakModeTailTruncation is deprecated as of iOS 6.Vanillin
C
1
[txt_field setValue:ColorFromHEX(@"#525252") forKeyPath:@"_placeholderLabel.textColor"];
Carlacarlee answered 23/4, 2014 at 9:34 Comment(1)
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. :)Aprilette
D
1

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
    }
}
Deboradeborah answered 7/12, 2017 at 5:38 Comment(0)
P
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..)

Peirce answered 6/12, 2010 at 22:34 Comment(1)
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.Feverish
P
-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

Photoflood answered 9/8, 2011 at 21:0 Comment(2)
I don't think the placeholder actually uses the textColor.Basting
I can confirm that the placeholder doesn't use the textColor property.Organization

© 2022 - 2024 — McMap. All rights reserved.