Подтвердить что ты не робот

UITextField текст заполнителя: отрегулируйте, чтобы соответствовать

У меня есть UITextField с более длинным текстом, установленным в качестве заполнителя. Я хочу, чтобы этот текст заполнителя изменял размер шрифта, когда ширина поля слишком мала.

Я уже пробовал это решение, описанное в других сообщениях (программно и в IB)

self.fieldTest.adjustsFontSizeToFitWidth = true
self.fieldTest.minimumFontSize = 10.0

Что мне здесь не хватает?

4b9b3361

Ответ 1

Вы можете создать подкласс UITextField:

class AutoSizeTextField: UITextField {
    override func layoutSubviews() {
        super.layoutSubviews()

        for subview in subviews {
            if let label = subview as? UILabel {
                label.minimumScaleFactor = 0.3
                label.adjustsFontSizeToFitWidth = true
            }
        }
    }
}    

Или вы можете просто добавить код в свой контроллер просмотра viewDidAppear:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    for subview in fieldTest.subviews {
        if let label = subview as? UILabel {
            label.minimumScaleFactor = 0.3
            label.adjustsFontSizeToFitWidth = true
        }
    }
}

Ответ 2

Здесь вы идете:

_myTextField.placeholder = @"SomeTextSomeTextSome";
UILabel *label = [_myTextField valueForKey:@"_placeholderLabel"];
label.adjustsFontSizeToFitWidth = YES;

Ура!!

Ответ 3

На основании ответа 9: в раскадровке перейдите на вкладку инспектора идентификации элемента текстового поля и в разделе "Определенные пользователем атрибуты времени выполнения" добавьте следующее:

enter image description here

Ответ 4

Изучив ссылку на класс для UITextField, кажется, что AdjustmentsFontSizeToFitWidth влияет только на текстовое свойство UITextField, а не на свойство заполнителя. Несмотря на то, что я не знаю, каким образом можно заставить заполнитель реагировать на AdjusttsFontSizeToFitWidth, я могу предложить две хакерские идеи, которые могут дать вам желаемый вид. Просто знайте, что я не рядом с Mac прямо сейчас, поэтому я не проверял эти идеи:

1:
Поскольку местозаполнителем является просто текст с 70% серого цвета, вы можете установить свойство текста метки таким, каким оно вам нужно, а затем реализовать метод UITextFieldDelegate textFieldShouldBeginEditing, чтобы очистить текст и вернуть цвет к нормальному. Вам также потребуется реализовать методы textFieldShouldClear и textFieldDidEndEditing, чтобы заменить псевдо-заполнитель обратно в UITextField и изменить цвет текста обратно на 70% серый.

2:
В viewWillAppear вы можете установить для текста UITextField то, каким должен быть ваш местозаполнитель, создать объект UIFont и установить его равным свойству шрифта UITextField, очистить текст UITextField и установить в качестве заполнителя NSAttributedString с объектом шрифта в качестве свойства. Вот пример того, что я имею в виду:

-(void)viewWillAppear:(BOOL) animated {
    [super viewWillAppear:animated];
    someTextField.adjustsFontSizeToFitWidth = YES;
    someTextField.text = @"placeholderText";
    UIFont *font = someTextField.font;
    someTextField.text = nil;
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
    NSAttributedString *placeholderString= [[NSAttributedString alloc] initWithString:@"placeholderText" attributes:attributes];
    someTextField.placeholder = placeholderString;
}

Изменение: только что заметил быстрый тег. Я написал свой код в Objective-C, но вы сможете легко перевести его на Swift.

Ответ 5

Здесь решение, зависящее от недокументированного факта, что UITextField имеет дочерний элемент UILabel (фактически UITextFieldLabel) для рендеринга заполнителя. Преимущество этого решения над некоторыми другими заключается в том, что он изящно ухудшается при изменении Apple. Он также не делает предположений о существовании недокументированных иваров.

В основном мы расширяем UILabel через категорию. Если мы видим, что мы являемся родителями для UITextField, тогда мы включаем adjustFontSizeToFitWidth.

@interface UILabel (TS)
@end

@implementation UILabel (TS)

- (void) didMoveToSuperview
{
    [super didMoveToSuperview];

    if ( [self.superview isKindOfClass: [UITextField class]] ) {

        self.adjustsFontSizeToFitWidth = YES;
    }
}

@end

Ответ 6

 override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
       for subView in fieldTest.subviews{
        if subView .isKind(of: UILabel.self){
            let label = subView as! UILabel
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.2
        }
    }     
}

Ответ 7

Swift

Не стесняйтесь улучшать расширение - довольно уверен, что есть более элегантный способ перебора надзонов.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    tfCountryCode.allSubviewsOfClass(UILabel.self).forEach {
        $0.adjustsFontSizeToFitWidth = true
        $0.minimumScaleFactor = 0.5
    }
}

extension UIView {
    func allSubviewsOfClass<K: UIView>(_ clazz: K.Type) -> [K] {
        var matches = [K]()
        if subviews.isEmpty { return matches }
        matches.append(contentsOf: subviews.filter { $0 is K } as! [K])
        let matchesInSubviews = subviews.flatMap { return $0.allSubviewsOfClass(clazz) }
        matches.append(contentsOf: matchesInSubviews.flatMap { $0 })
        return matches
    }
}

Ответ 8

Вы можете использовать эти два решения:

1.Если у вас установлен фиксированный размер шрифта, если размер текстового поля меньше текста заполнителя:

    let placeholderString = testTF.placeholder

    print(placeholderString!)

    let font = UIFont(name: (testTF.font?.fontName)!, size: 16)!

    let fontAttributes = [NSFontAttributeName: font]

    let size = (placeholderString! as NSString).sizeWithAttributes(fontAttributes)

    print(size)
    print(testTF.frame.size.width)
    if(size.width > testTF.frame.size.width)
    {
        let font = UIFont(name: (testTF.font?.fontName)!, size: 4)!
        let attributes = [
            NSForegroundColorAttributeName: UIColor.lightGrayColor(),
            NSFontAttributeName : font]

        testTF.attributedPlaceholder = NSAttributedString(string: placeholderString!,
                                                          attributes:attributes)


    }
    else
    {
    let attributes = [
        NSForegroundColorAttributeName: UIColor.lightGrayColor(),
        NSFontAttributeName : font]

    testTF.attributedPlaceholder = NSAttributedString(string: placeholderString!,
                                                         attributes:attributes)
    }

2) Если вам нужен динамический размер шрифта, чем вы просто проверяете вышеприведенное условие для ширины текстового поля и текста шрифта size.width. если размер текста заполнителя больше размера текстового поля, чем создание одной метки внутри текстового поля и установка минимального шрифта на этом.

if (size.width > testTF.frame.size.width)       {

        placeholder = UILabel(frame: CGRect( x: 0, y: 0, width: testTF.bounds.width, height: testTF.bounds.height))
        placeholder.text = placeholderString
        placeholder.numberOfLines = 1;
        //placeholder.minimumScaleFactor = 8;
        placeholder.adjustsFontSizeToFitWidth = true
        placeholder.textColor = UIColor.grayColor()
        placeholder.hidden = !testTF.text!.isEmpty
        placeholder.textAlignment = .Center
        testTF.addSubview(placeholder)

}

Ответ 9

В Swift

yourTextField.subviews
        .filter { $0 is UILabel }
        .flatMap { $0 as? UILabel }
        .forEach {
            $0.adjustsFontSizeToFitWidth = true
            $0.minimumScaleFactor = 0.5
        }

он работает:)

Ответ 10

Попробуйте использовать атрибутный placeholder вместо обычного владельца места.

Попробуйте это

let attributedplaceholder = NSAttributedString(string: "placeholdertext", attributes: [NSFontAttributeName: UIFont(name: "FontName", size: 10)!])
self.fieldTest.attributedPlaceholder = attributedplaceholder

Вы можете добавить дополнительные атрибуты к заполнителю, например textcolor и другие

Ответ 11

Весь подход или уменьшающийся размер шрифта для соответствия вводится в заблуждение в день и возраст доступности.

Во-первых, у вас есть нулевой бизнес, определяющий размер текста, в первую очередь, не говоря уже о сокращении этого: вы должны полагаться на API доступности.

Таким образом, если местозаполнитель не подходит, он должен быть помещен как UILabel, предшествующий UITextField. Заместители должны быть короткими и соответствовать без клипа.

Чтобы определить, если он обрезается, я предполагаю, что вы можете использовать ограничения (CGRect) placeholderRectForBounds: (CGRect); но тогда вы находитесь в мутные воды с использованием API, который Apple говорит, что вы должны переопределять (но не называть себя, даже если он, вероятно, имеет смысл и безопасен в пределах метода didlayoutsubviews [s])

Если текст заполнителя является динамическим (сервер обслуживается), выгрузите его в UILabel.