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.
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]];
}
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.
}
Facile et sans douleur, pourrait être une alternative facile pour certains.
_placeholderLabel.textColor
Non suggéré pour la production, Apple peut rejeter votre soumission.
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}];
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.
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])
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])
}
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}];
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)
}
}
}
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)
}
}
}
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"];
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.
Pourquoi n'utilisez-vous pas la méthode UIAppearance
:
[[UILabel appearanceWhenContainedIn:[UITextField class], nil] setTextColor:[UIColor whateverColorYouNeed]];
[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é.
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 });
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
}
}
}
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
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.
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
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;
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;
}
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: |
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];
}
}
[txt_field setValue:ColorFromHEX(@"#525252") forKeyPath:@"_placeholderLabel.textColor"];
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);
}
}
dans Swift 3.X
passwordTxtField.attributedPlaceholder = NSAttributedString(string: "placeholder text", attributes:[NSForegroundColorAttributeName: UIColor.black])
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];
}
Cette solution pour Swift 4.1
textName.attributedPlaceholder = NSAttributedString(string: textName.placeholder!, attributes: [NSAttributedStringKey.foregroundColor : UIColor.red])
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: -
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
}
}
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 ..)