I have a UITextField
on a table view cell, and when it\'s text becomes too long I would like the font size to decrease. I want to make it very clear that I am t
I had this same problem with UITextFields created in StoryBoard in Xcode 5.0.2, running iOS 7.0.4. I figured out that the .minimumFontSize property could not be changed by StoryBoard, or viewDidLoad, or viewWillAppear, but that it could be changed in viewDidAppear. So the following code solved my problem:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.myTextField.minimumFontSize = 4.0;
[self.myTextField setNeedsLayout];
[self.myTextField layoutIfNeeded];
}
I used the answer posted by @Purva as a starting point to come up with this method that gives the required font size starting at the configured font size, and not to drop below the configured minimum font size. Whereas @Purva tested for the height of the text I required the width to fit. This method can be put in either a category or a subclass of UITextField. I have it in a subclass which also captures the UITextFieldTextDidChangeNotification
. From this notification handler I call the new method and resize the font if required. I also call it when I am assigning new text to the textfield to make sure it will fit by subclassing - (void)setText: (NSString*)text
.
In each case, when I call it I am using the following code:
CGFloat requiredFontSize = self.requiredFontSize;
if( self.font.pointSize != requiredFontSize )
{
self.font = [self.font fontWithSize: requiredFontSize];
}
Here is the new method:
- (CGFloat)requiredFontSize
{
const CGRect textBounds = [self textRectForBounds: self.frame];
const CGFloat maxWidth = textBounds.size.width;
if( _originalFontSize == -1 ) _originalFontSize = self.font.pointSize;
UIFont* font = self.font;
CGFloat fontSize = _originalFontSize;
BOOL found = NO;
do
{
if( font.pointSize != fontSize )
{
font = [font fontWithSize: fontSize];
}
CGSize size = [self.text sizeWithFont: font];
if( size.width <= maxWidth )
{
found = YES;
break;
}
fontSize -= 1.0;
if( fontSize < self.minimumFontSize )
{
fontSize = self.minimumFontSize;
break;
}
} while( TRUE );
return( fontSize );
}
Tested with XCode8 and Swift 3.0.1
func getTextfield(view: UIView) -> [UITextField] {
var results = [UITextField]()
for subview in view.subviews as [UIView] {
if let textField = subview as? UITextField {
results += [textField]
} else {
results += getTextfield(view: subview)
}
}
return results
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let allTextFields = getTextfield(view: self.view)
for textField in allTextFields
{
textField.font = UIFont.boldSystemFont(ofSize: 14)
var widthOfText: CGFloat = textField.text!.size(attributes: [NSFontAttributeName: textField.font!]).width
var widthOfFrame: CGFloat = textField.frame.size.width
while (widthOfFrame - 15) < widthOfText { // try here to find the value that fits your needs
let fontSize: CGFloat = textField.font!.pointSize
textField.font = textField.font?.withSize(CGFloat(fontSize - 0.5))
widthOfText = (textField.text?.size(attributes: [NSFontAttributeName: textField.font!]).width)!
widthOfFrame = textField.frame.size.width
}
}
}
I used viewDidLayoutSubviews to get all textfields and autoshrink the text.
Maybe someone will need this code.
For me it works perfect.
The Code is from@ Marek Manduch on this site and from
@Kunal Kumar on this site: How to get all the textfields from a view in swift
I think you want to set the adjustsFontSizeToFitWidth
property for your UITextField
to YES, and specify a minimumFontSize
. Works for me, but I add the UITextField
programmatically - IB issue?
The catch here is that minimumFontSize is a ratio and should be between 0 and 1 :)
f.adjustsFontSizeToFitWidth = true
f.minimumFontSize = 0.5
works perfectly :)