27

在 iOS 13 中,我在访问UITextField_placeholderLabel.textColor 标签键时遇到了崩溃。

用于应用占位符文本颜色的键。

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

“NSGenericException” - 原因:“禁止访问 UITextField 的 _placeholderLabel ivar。这是一个应用程序错误”

4

15 回答 15

28

您可以使用运行时来做到这一点:

将以下代码添加到占位符设置的底部

Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
UILabel *placeholderLabel = object_getIvar(textField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];

在 Xcode 11 beta2 中,这个代码是可以工作的,但我不知道是 GM 版本还是官方版本。

完整代码:

  • Objective-C 版本

#import "ViewController.h"
#import <objc/runtime.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor grayColor];
    self.title = @"UITextField Demo";

    UITextField *textField = [UITextField new];
    textField.frame = CGRectMake(0, 100, 300, 50);
    textField.placeholder = @"UITextField Demo";
    [self.view addSubview:textField];

    Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
    UILabel *placeholderLabel = object_getIvar(textField, ivar);

    placeholderLabel.textColor = [UIColor whiteColor];
}

@end
  • 斯威夫特版本:
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        let textField = UITextField()
        textField.frame = CGRect(x: 0, y: 100, width: 300, height: 50)
        textField.placeholder = "UITextField Demo"
        view.addSubview(textField)

        let iVar = class_getInstanceVariable(UITextField.self, "_placeholderLabel")!
        let placeholderLabel = object_getIvar(textField, iVar) as! UILabel
        placeholderLabel.textColor = .red
    }
}

2019/09/25 更新

上述实现可以解决问题,但不提倡。

使用私有 api 的应用程序将来可能会损坏。

请使用新的 api:

var attributedPlaceholder: NSAttributedString? { get set }

讨论

此属性默认为 nil。如果设置,则使用系统定义的颜色和属性字符串的剩余样式信息(文本颜色除外)绘制占位符字符串。为该属性分配一个新值也会用相同的字符串数据替换占位符属性的值,尽管没有任何格式信息。为该属性分配新值不会影响文本字段的任何其他与样式相关的属性。

完整代码:

let textField = UITextField()
textField.frame = CGRect(x: 0, y: 100, width: 300, height: 50)
let placeholderString = NSAttributedString.init(string: "UITextField Demo", attributes: [NSAttributedString.Key.foregroundColor : UIColor.red])
textField.attributedPlaceholder = placeholderString
view.addSubview(textField)

于 2019-06-26T15:42:37.277 回答
14

我认为这是 XCode 方面的一个错误,希望他们会在下一个版本中修复这个错误。您可以通过擦除模拟器设备上的所有内容和设置来快速解决此问题。

在此处输入图像描述

于 2019-10-29T12:17:03.640 回答
12

是的,这个问题与 Xcode 版本有关。我有 Xcode 11.2.1,我面临同样的问题。

_placeholderLabel.textColor

如果您将情节提要中的它用作运行时变量并遇到问题,那么只需删除“_”

像那样 在此处输入图像描述

删除“_”运行时 Var 后开始工作

于 2019-12-07T13:39:47.680 回答
10

删除下划线“_”并试试这个。

[textfield setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];

它应该适用于所有版本!

于 2019-11-18T06:01:34.907 回答
8

我是这样做的:

对象

NSMutableAttributedString *placeholderAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:searchField.attributedPlaceholder];
[placeholderAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, [placeholderAttributedString length])];
searchField.attributedPlaceholder = placeholderAttributedString;

斯威夫特 5

var placeholderAttributedString = NSMutableAttributedString(attributedString: searchField.attributedPlaceholder)
    placeholderAttributedString.addAttribute(.foregroundColor, value: UIColor.red, range: NSRange(location: 0, length: placeholderAttributedString.length))
    searchField.attributedPlaceholder = placeholderAttributedString

这有点长,但我目前没有更好的。

于 2019-09-10T11:45:49.577 回答
3

如果您使用的是 UITextView+Placeholder.h 类,请更改下面的方法 Clean and build 如果问题仍然存在

目标 C

+(UIColor *)defaultPlaceholderColor {

    static UIColor *color = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        UITextField *textField = [[UITextField alloc] init];
        textField.placeholder = @" ";
        //        color = [textField valueForKeyPath:@"_placeholderLabel.textColor"];
        Ivar ivar =  class_getInstanceVariable([UITextField class], "_placeholderLabel");
        UILabel *placeholderLabel = object_getIvar(textField, ivar);
        color =  placeholderLabel.textColor;

    });
    return color;

}
于 2019-10-09T04:25:45.847 回答
2

您可以UITextField使用以下方法设置占位符文本颜色、字体attributedPlaceholder

NSString *text = [textField text];
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:text attributes:@{NSForegroundColorAttributeName: [UIColor redColor], NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Medium" size:14.0f]}];
于 2019-08-21T07:21:28.987 回答
2

“删除所有内容和设置”

这对我有用。

于 2019-09-25T17:46:25.233 回答
2

我删除了“用户定义的运行时属性”部分中的 var“_placeholderLabel” 在此处输入图像描述

于 2019-11-14T14:21:58.907 回答
2

只需替换_placeholderLabelplaceholderLabel

于 2020-01-16T15:17:27.607 回答
1

对于 IOS 13,您可以通过一行代码设置 UITextField 占位符颜色。

目标 C

[textField setAttributedPlaceholder:[[NSAttributedString alloc] initWithString:@"PlaceHolder Text" attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]];

斯威夫特 5

txtTitle.attributedPlaceholder = NSAttributedString(string:"PlaceHolder Text", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
于 2019-10-15T15:13:01.743 回答
0

- 斯威夫特版本

将以下代码添加到占位符设置的底部:

    let iVar = class_getInstanceVariable(UITextField.self, "_placeholderLabel")!
    let placeholderLabel = object_getIvar(textField, iVar) as! UILabel

    placeholderLabel.textColor = .white

例如:

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .gray

    let textField = UITextField()
    textField.frame = CGRect(x: 0, y: 100, width: 300, height: 50)
    textField.placeholder = "UITextField Demo"
    view.addSubview(textField)
    let iVar = class_getInstanceVariable(UITextField.self, "_placeholderLabel")!
    let placeholderLabel = object_getIvar(textField, iVar) as! UILabel

    placeholderLabel.textColor = .white
}
于 2019-09-16T10:08:18.167 回答
0

斯威夫特 5

这是该属性的正确 Swift 替换。请注意,如果您还更改了文本字段的其他属性的对齐方式,那么您也需要将这些属性设置为占位符的属性文本。通常只改变颜色和字体:

/// Set placeholder text color
/// - Parameter color: the color
func setPlaceholderColor(_ color: UIColor) {
    // Color
    var attributes: [NSAttributedString.Key: Any] = [.foregroundColor: color]
    var range = NSRange(location: 0, length: 1)

    // Font
    if let text = attributedText, text.length > 0, let attrs = attributedText?.attributes(at: 0, effectiveRange: &range), let font = attrs[.font] {
        attributes[.font] = font
    }
    else if let font = font {
        attributes[.font] = font
    }
    self.attributedPlaceholder = NSAttributedString(string: self.placeholder ?? "", attributes: attributes)
}
于 2019-09-28T09:12:14.760 回答
0

用于 UISearchBAR 占位符颜色

Xcode 11.1

从 iOS 13 开始,SDK 提供UISearchBar.searchTextField,因此我们可以使用公共 API 而不是私有 API。在UISearchBar的子类中,我使用此代码更改占位符颜色

UITextField *textField = [self findSubviewOfClass:[UITextField class]];
textField.textColor = [UIColor whiteColor];
//textField.font = [UIFont fontWithName:@"HelveticaNeue-Regular" size:14.0f];

if (@available(iOS 13.0, *)) {
    self.searchTextField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder attributes:@{NSForegroundColorAttributeName: [UIColor colorWithRed:0.8 green:0.82 blue:0.81 alpha:1]}];

}else {
    [textField setValue:[UIColor colorWithRed:0.8 green:0.82 blue:0.81 alpha:1] forKeyPath:@"_placeholderLabel.textColor"];

}
于 2019-10-15T06:42:21.413 回答
0

删除“_”表单“_placeholderLabel.textColor”尝试使用“placeholderLabel.textColor”。

于 2021-05-21T16:32:28.727 回答