我想改变我在UITextField控件中设置的占位符文本的颜色,使其为黑色。

我更喜欢这样做,而不使用普通文本作为占位符,并且不得不重写所有方法来模仿占位符的行为。

我相信如果我重写这个方法:

- (void)drawPlaceholderInRect:(CGRect)rect

那么我就能做这个了。但是我不确定如何从这个方法中访问实际的占位符对象。


当前回答

iOS 6及后续版本在UITextField上提供attributedPlaceholder。 iOS 3.2及更高版本提供了setAttributes:range: on NSMutableAttributedString。

您可以执行以下操作:

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;

其他回答

小心谨慎。

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

需要注意的是,你必须在“DON'T_DELETE”所在的地方输入一个非空字符串,即使该字符串在其他地方的代码中设置了。也许能帮你省下五分钟的脑筋。

如果子类化你必须做layoutSubviews(不是在init) 奇怪的是,你不需要清除正常的占位符。如果你使用带属性的占位符,它知道不绘制占位符。

我需要保持占位符的对齐,这样亚当的答案对我来说就不够了。

为了解决这个问题,我使用了一个小的变化,我希望也能帮助到你们:

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

也许你想尝试这种方式,但苹果可能会警告你访问私有ivar:

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

请注意 根据Martin Alléus的说法,iOS 7不再适用了。

适用于iOS 6.0 +

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

希望能有所帮助。

注意:苹果可能会拒绝(0.01%的机会)你的应用程序,因为我们正在访问私有API。这两年以来,我一直在我的所有项目中使用这个功能,但苹果并没有要求我这么做。

重写drawPlaceholderInRect:将是正确的方式,但由于API(或文档)中的错误,它不起作用。

该方法永远不会在UITextField上被调用。

参见drawTextInRect on UITextField not called

你可以使用digdog的解决方案。因为我不确定这是否通过了苹果的审查,我选择了一个不同的解决方案:用我自己的标签覆盖文本字段,模仿占位符行为。

这有点乱。 代码看起来像这样(注意,我在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;
}