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

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

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

- (void)drawPlaceholderInRect:(CGRect)rect

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


当前回答

重写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;
}

其他回答

类别增值。可以优化检查有效的颜色变化。


#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

重写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;
}

我建议另一种解决办法。由于占位符文本使用文本字段的默认字体设置,只需将初始字体颜色设置为您想要的占位符字体颜色。然后设置你的UITextField的委托并实现以下方法:

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

因此,如果用户开始在文本框中输入文本的颜色改变为黑色,在文本框再次被清除后,占位符文本将再次出现红色。

干杯, 安卡

你为什么不直接使用UIAppearance方法:

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

适用于iOS 6.0 +

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

希望能有所帮助。

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