Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField placeholder text: adjust to fit

I have UITextField with longer text in it set as placeholder. What I want is for this placeholder text to adjust its font size when the width of field is too small.

I already tried this solution described in other posts (programmatically and in IB)

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

What am I missing here?

like image 222
spafrou Avatar asked Nov 19 '15 13:11

spafrou


5 Answers

You can create a subclass of 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
            }
        }
    }
}    

Or you can just add some code in your view controller's 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
        }
    }
}
like image 102
wj2061 Avatar answered Nov 19 '22 18:11

wj2061


Here you go :

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

Cheers!!

like image 17
sashi_bhushan Avatar answered Nov 19 '22 17:11

sashi_bhushan


Based on answer 9: in Storyboard go to the identity inspector tab of the text field element, and under the "User Defined Runtime Attributes" section, add the following:

enter image description here

like image 5
Arik Segal Avatar answered Nov 19 '22 17:11

Arik Segal


Here's a solution that depends on the undocumented fact that the UITextField has a child UILabel (actually UITextFieldLabel) to render the placeholder. The advantage of this solution over some others is that it degrades gracefully should Apple's implementation change. It also doesn't make assumptions about the existence of undocumented ivars.

Basically we extend UILabel via a category. If we see ourselves being parented to a UITextField then we turn on adjustFontSizeToFitWidth.

@interface UILabel (TS)
@end

@implementation UILabel (TS)

- (void) didMoveToSuperview
{
    [super didMoveToSuperview];

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

        self.adjustsFontSizeToFitWidth = YES;
    }
}

@end
like image 2
TomSwift Avatar answered Nov 19 '22 18:11

TomSwift


After reviewing the class reference for UITextField's, it seems that adjustsFontSizeToFitWidth only affects the the text property of the UITextField and not the placeholder property. While I don't know off the top of my head a way to get the placeholder to respond to adjustsFontSizeToFitWidth, I can suggest two hacky ideas that may give you the appearance that you want. Just be aware that I'm not near a Mac right now so I haven't tested these ideas:

1:
Since a placeholder is just text with a 70% gray color, you could set the label's text property to be whatever you need it to be, and then implement the UITextFieldDelegate's textFieldShouldBeginEditing method to clear the text and change the color back to normal. You would also have to implement the textFieldShouldClear and textFieldDidEndEditing methods to replace the pseudo-placeholder back in the UITextField and change the text color back to 70% gray.

2:
In viewWillAppear you could set the UITextField's text to what your placeholder should be, create a UIFont object and set it equal to the UITextField's font property, clear the UITextField's text, and set the placeholder to be an NSAttributedString with the font object as a property. Here's an example of what I mean:

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

Edit: Just noticed the swift tag. I wrote my code in Objective-C, but you should be able to easily translate it to Swift.

like image 2
tww0003 Avatar answered Nov 19 '22 16:11

tww0003