В iOS 13 у меня возникает сбой при доступе к ключу метки UITextField _placeholderLabel.textColor.
Ключ, используемый для применения цвета текста-заполнителя.
[textfield setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
"NSGenericException" - reason: "Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug"
@SunilTarge проверить ответы - stackoverflow.com/a/56776561/3560390
Это не "проблема". Запрещено ковыряться во внутренних деталях реализации. Вы нарушаете правила App Store. Любой «обходной путь», который вы попытаетесь сделать, скоро снова будет сломан. Останавливаться.
@PrasathBabu это замораживание предназначено только для симулятора, верно? пока в реальном устройстве не зависает, то это не проблема? Я начинающий. Я смущен, потому что у меня нет этого зависания на реальном устройстве, а только в симуляторе. так что, если меня не волнует симулятор, мне не нужно добавлять ответы ниже, верно? пожалуйста, очень нужна ваша информация
@ Alexa289 Alexa289 На устройстве происходит сбой — когда вы создаете приложение с помощью Xcode11 и iOS 13 Device. Сбой не происходит, если приложение собирается до Xcode11 и устанавливается на устройство iOS 13.
@PrasathBabu Я не пробовал на iOS 13, но только что попробовал на iOS 13.1.3 и не обнаружил проблем на своем реальном устройстве. просто зависаю на симуляторе. вот почему у меня есть сомнения, добавлять код ниже (ответ) или нет





Вы можете сделать это с помощью среды выполнения:
добавьте следующий код в нижнюю часть настройки заполнителя
Ivar ivar = class_getInstanceVariable([UITextField class], "_placeholderLabel");
UILabel *placeholderLabel = object_getIvar(textField, ivar);
placeholderLabel.textColor = [UIColor whiteColor];
В Xcode 11 beta2 этот код работает, но я не знаю о версии GM или официальной версии.
Полный код:
#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
}
}
Вышеупомянутая реализация может решить проблему, но не рекомендуется.
Приложения, использующие частный API, могут быть сломаны в будущем.
Пожалуйста, используйте новый API:
var attributedPlaceholder: NSAttributedString? { get set }
Обсуждение
This property is nil by default. If set, the placeholder string is drawn using system-defined color and the remaining style information (except the text color) of the attributed string. Assigning a new value to this property also replaces the value of the placeholder property with the same string data, albeit without any formatting information. Assigning a new value to this property does not affect any other style-related properties of the text field.
Полный код:
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)
Спасибо. Эта «ошибка» все еще существует в бета-версии 6. Написал это на Swift и работает там же.
С какой стати вы рекомендуете людям делать что-то явно недопустимое, публикуя другой обходной путь? Это не нормально, прекратите это делать. Ваши приложения будут сломаны в будущем.
@russbishop какое-нибудь решение, как его изменить? Спасибо
@russbishop Спасибо, что напомнили. Я обновил свой ответ.
@iDevOrz четко написано в документах: «Если установлено, строка-заполнитель рисуется с использованием определенного системой цвета и оставшейся информации о стиле (кроме цвета текста)». Значит, вы не ответили на вопрос в своем обновлении.
Изменение цвета текста заполнителя не поддерживается UIKit, но отзывы об этом приветствуются. Вы можете использовать attributedPlaceholderString для изменения атрибутов стиля разное текста-заполнителя.
@Mikhail Maslo, спасибо за напоминание,Но когда я встраиваю Xcode 11 и запускаю iOS 12.2 и iOS 13 Simulator, у меня это сработало. Как это странно!
Вы можете установить UITextField цвет текста заполнителя, шрифт, используя attributedPlaceholder метод следующим образом:
NSString *text = [textField text];
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:text attributes:@{NSForegroundColorAttributeName: [UIColor redColor], NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Medium" size:14.0f]}];
Я сделал это следующим образом:
Объект
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
Это немного долго, но у меня нет ничего лучше на данный момент.
Единственный приемлемый ответ на данный момент, я использую Xcode 11.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
}
«Удалить все содержимое и настройки»
Это сработало для меня.
Свифт 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)
}
если вы используете класс UITextView+Placeholder.h, измените метод ниже. Очистите и создайте, если проблема не устранена.
Цель С
+(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;
}
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"];
}
Для IOS 13 вы можете установить цвет заполнителя UITextField с помощью кода одной строки.
Цель С
[textField setAttributedPlaceholder:[[NSAttributedString alloc] initWithString:@"PlaceHolder Text" attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]];
В Свифт 5
txtTitle.attributedPlaceholder = NSAttributedString(string:"PlaceHolder Text", attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
Удалите подчеркивание "_" и попробуйте это.
[textfield setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
Должно работать на всех версиях!
Это сработало для меня в симуляторе и Xcode 11.2.1. Спасибо
Просто замените _placeholderLabel на placeholderLabel
Удалите "_" из формы "_placeholderLabel.textColor", попробуйте с "placeholderLabel.textColor".
Эта проблема существует и в Семена Xcode 11 GM.