web-dev-qa-db-fra.com

iPhone UITextField - Change la couleur du texte de l'espace réservé

J'aimerais changer la couleur du texte de substitution que j'ai défini dans mes contrôles UITextField pour le rendre noir.

Je préférerais le faire sans utiliser de texte normal en tant qu'espace réservé et de devoir redéfinir toutes les méthodes pour imiter le comportement d'un espace réservé.

Je crois que si je remplace cette méthode:

- (void)drawPlaceholderInRect:(CGRect)rect

alors je devrais pouvoir le faire. Mais je ne sais pas comment accéder à l'objet d'espace réservé réel à partir de cette méthode.

525
adam

Vous pouvez remplacer drawPlaceholderInRect:(CGRect)rect en tant que tel pour restituer manuellement le texte de substitution:

- (void) drawPlaceholderInRect:(CGRect)rect {
    [[UIColor blueColor] setFill];
    [[self placeholder] drawInRect:rect withFont:[UIFont systemFontOfSize:16]];
}
194
adam

Depuis l'introduction de chaînes attribuées dans UIViews dans iOS 6, il est possible d'attribuer une couleur au texte de substitution comme suit:

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.
}
782
user1071136

Facile et sans douleur, pourrait être une alternative facile pour certains.

_placeholderLabel.textColor

Non suggéré pour la production, Apple peut rejeter votre soumission.

236
Jack

Vous pouvez modifier la couleur du texte d'espace réservé pour la couleur de votre choix à l'aide du code ci-dessous.

UIColor *color = [UIColor lightTextColor];
YOURTEXTFIELD.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"PlaceHolder Text" attributes:@{NSForegroundColorAttributeName: color}];
162
Manju

Vous voudrez peut-être essayer de cette façon, mais Apple pourrait vous prévenir de l'accès à ivar privé:

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

REMARQUE
Cela ne fonctionne plus sur iOS 7, selon Martin Alléus.

157
digdog

Cela fonctionne dans Swift <3.0: 

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

Testé sous iOS 8.2 et 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])
122
Tomino

En rapide:

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

Dans Swift 4.0:

if let placeholder = yourTextField.placeholder {
    yourTextField.attributedPlaceholder = NSAttributedString(string:placeholder, 
        attributes: [NSAttributedStringKey.foregroundColor: UIColor.black])
}
63
Beninho85

Ce qui suit uniquement avec iOS6 + (comme indiqué dans le commentaire d'Alexander W):

UIColor *color = [UIColor grayColor];
nameText.attributedPlaceholder =
   [[NSAttributedString alloc]
       initWithString:@"Full Name"
       attributes:@{NSForegroundColorAttributeName:color}];
43
Gaurav Gilani

Swift 3.0 + Storyboard

Afin de changer la couleur des espaces réservés dans le storyboard, créez une extension avec le code suivant. (n'hésitez pas à mettre à jour ce code, si vous pensez qu'il peut être plus clair et plus sûr).

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)
        }
    }
}
38
Nik Kov

Avec cela, nous pouvons changer la couleur du texte de substitution de textfield dans 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"];
32
Uma Madhavi

J'avais déjà fait face à ce problème. Dans mon cas, le code ci-dessous est correct. 

Objectif c

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

Pour Swift 4.X

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

J'espère que cela peut vous aider.

22
Ashu

Pourquoi n'utilisez-vous pas la méthode UIAppearance:

[[UILabel appearanceWhenContainedIn:[UITextField class], nil] setTextColor:[UIColor whateverColorYouNeed]];
19
Valerii Lider

Aussi dans votre story-board, sans une seule ligne de code

 enter image description here

17
Petr Syrov

Pour iOS 6.0 +

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

J'espère que ça aide.

Remarque:Apple peut rejeter (0,01% de chances) votre application car nous avons accès à une API privée. J'utilise cela dans tous mes projets depuis deux ans, mais Apple ne l'a pas demandé.

12
Fahim Parkar

Pour les développeurs Xamarin.iOS, je l’ai trouvé dans ce document https://developer.xamarin.com/api/type/Foundation.NSAttributedString/

textField.AttributedPlaceholder = new NSAttributedString ("Hello, world",new UIStringAttributes () { ForegroundColor =  UIColor.Red });
10
ManuQiao

Version rapide. Cela aiderait probablement quelqu'un.

class TextField: UITextField {
   override var placeholder: String? {
        didSet {
            let placeholderString = NSAttributedString(string: placeholder!, attributes: [NSForegroundColorAttributeName: UIColor.whiteColor()])
            self.attributedPlaceholder = placeholderString
        }
    }
}
9
Max Tymchii

Catégories FTW. Pourrait être optimisé pour vérifier le changement de couleur effectif.


#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
6
osxdirk

Pour gérer l'alignement vertical et horizontal ainsi que la couleur de l'espace réservé dans iOS7. drawInRect et drawAtPoint n'utilisent plus le contexte actuel 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
6
aumansoftware

iOS 6 et versions ultérieures offre attributedPlaceholder sur UITextField. iOS 3.2 et versions ultérieures offrent setAttributes:range: sur NSMutableAttributedString.

Vous pouvez faire ce qui suit: 

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;
5
William Power

Remplacer drawPlaceholderInRect: serait la bonne façon, mais cela ne fonctionne pas à cause d'un bogue dans l'API (ou la documentation).

La méthode n'est jamais appelée sur une UITextField.

Voir aussi drawTextInRect sur UITextField non appelé

Vous pouvez utiliser la solution digdog. Comme je ne suis pas sûr si cela va au-delà de l'examen d'Apple, j'ai choisi une solution différente: superposer le champ de texte avec ma propre étiquette imitant le comportement d'espace réservé.

Ceci est un peu compliqué cependant ... Le code ressemble à ceci (Notez que je le fais dans une sous-classe de 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;
}
4
henning77

Je suis nouveau sur xcode et j'ai trouvé un moyen d'obtenir le même effet.

J'ai placé un uilabel à la place d'un espace réservé au format souhaité et le cache dans 

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

        case 1:
            lblPassword.hidden=YES;
            break;

        default:
            break;
    }
}

Je suis d’accord pour dire que c’est un moyen de contourner la situation et non une solution réelle, mais l’effet obtenu était identique à celui obtenu de cette link

NOTE: Fonctionne toujours sur iOS 7: |

3
amar

Le mieux que je puisse faire pour iOS7 et moins est:

- (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];
  }
}
2
Aleksei Minaev
[txt_field setValue:ColorFromHEX(@"#525252") forKeyPath:@"_placeholderLabel.textColor"];
2
Mubin Shaikh

Pour ceux qui utilisent Monotouch (Xamarin.iOS), voici la réponse d'Adam traduite en C #:

public class MyTextBox : UITextField
{
    public override void DrawPlaceholder(RectangleF rect)
    {
        UIColor.FromWhiteAlpha(0.5f, 1f).SetFill();
        new NSString(this.Placeholder).DrawString(rect, Font);
    }
}
2
Diego

dans Swift 3.X

passwordTxtField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes:[NSForegroundColorAttributeName: UIColor.black])
2
MAhipal Singh

J'avais besoin de garder l'alignement d'espace réservé afin que la réponse d'Adam ne me suffise pas.

Pour résoudre ce problème, j'ai utilisé une petite variante qui, je l'espère, aidera également certains d'entre vous:

- (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];
}
1
Tomer Even

Cette solution pour Swift 4.1 

    textName.attributedPlaceholder = NSAttributedString(string: textName.placeholder!, attributes: [NSAttributedStringKey.foregroundColor : UIColor.red])
1
Mantosh Kumar

Pour définir un espace réservé de champ de texte attribué avec plusieurs couleurs, 

Il suffit de spécifier le texte,

  //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;

Sortie: - 

 enter image description here

1
Badal Shah

Dans 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
    }
}
0
Rob-4608

Une autre option qui ne nécessite pas de sous-classement - laissez l’espace réservé en blanc et mettez une étiquette au-dessus du bouton Modifier. Gérez l'étiquette comme vous le feriez avec l'espace réservé (effacement une fois que l'utilisateur a entré quelque chose ..)

0
kolinko