J'ai une UITextField
dans une cellule de la vue tableau et lorsque le texte devient trop long, j'aimerais que la taille de la police diminue. Je tiens à préciser très clairement que je parle d'une UITextField
, pas d'une UILabel
ou d'une UITextView
. La raison pour laquelle je dis cela est parce que j'ai vu cette question surgir plusieurs fois et les réponses étaient toutes basées sur UILabel
au lieu de UITextField
. Par exemple, quelqu'un a demandé "Je ne peux pas transférer ma UITextField
à la réduction automatique" et la réponse était "assurez-vous que numberOfLines
est défini sur 1
". À ma connaissance, un UITextField
ne possède même pas cette propriété et constitue un contrôle à une seule ligne.
J'ai essayé:
minFontSize
à 7 et cochant la case "ajuster pour s'adapter"tableView:cellForRowAtIndexPath:
ptCell.name.font = [UIFont systemFontOfSize: 14.0];
ptCell.name.adjustsFontSizeToFitWidth = YES;
ptCell.name.minimumFontSize = 7.0;
mais ni l'un ni l'autre n'ont fonctionné. J'entends par là qu'au lieu de réduire le texte, il tronque la queue.
Est-ce que quelqu'un sait ce que je manque? Cela devrait probablement fonctionner parce que j'ai vu d'autres questions se plaindre que l'utilisateur le fait quand l'utilisateur ne le souhaite pas.
J'ai utilisé la réponse publiée par @Purva comme point de départ pour trouver cette méthode qui donne la taille de police requise, en commençant par la taille de police configurée, et en ne dépassant pas la taille de police minimale configurée. Alors que @Purva a testé la hauteur du texte, il fallait que la largeur s’ajuste. Cette méthode peut être placée dans une catégorie ou une sous-classe de UITextField. Je l'ai dans une sous-classe qui capture également la UITextFieldTextDidChangeNotification
. Depuis ce gestionnaire de notification, j'appelle la nouvelle méthode et redimensionne la police si nécessaire. Je l'appelle aussi lorsque j'attribue un nouveau texte au champ de texte pour m'assurer qu'il conviendra au sous-classement - (void)setText: (NSString*)text
.
Dans chaque cas, lorsque j'appelle, j'utilise le code suivant:
CGFloat requiredFontSize = self.requiredFontSize;
if( self.font.pointSize != requiredFontSize )
{
self.font = [self.font fontWithSize: requiredFontSize];
}
Voici la nouvelle méthode:
- (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 );
}
J'ai eu le même problème. UITextField a cessé de réduire le texte quand il était trop long, mais au lieu de cela, il s'est redimensionné et a grandi en dehors de ses limites.
La solution qui m'a aidé était de définir width constraint sur un UITextField donné. Après cela, le texte à l'intérieur est devenu plus petit, comme prévu ... (bien sûr, vous devez définir minFontSize et cocher la case "ajuster à la taille" dans le scénario).
Je sais que c'est un peu tard, mais si quelqu'un d'autre trouve cette question via google comme je l'ai fait ... cela pourrait aider.
Je pense que vous souhaitez définir la propriété adjustsFontSizeToFitWidth
pour votre UITextField
sur YES et spécifier une minimumFontSize
. Cela fonctionne pour moi, mais j’ajoute la UITextField
par programme - problème d’IB?
Swift 3.0 façon de redimensionner la police pour l'adapter:
let startFontSize = 14.0
let minFontSize = 7.0
func resizeFont() {
guard let font = self.font, let text = self.text else {
return
}
let textBounds = self.textRect(forBounds: self.bounds)
let maxWidth = textBounds.size.width
for fontSize in stride(from: startFontSize, through: minFontSize, by: -0.5) {
let size = (text as NSString).size(attributes: [NSFontAttributeName: font.withSize(CGFloat(fontSize))])
self.font = font.withSize(CGFloat(fontSize))
if size.width <= maxWidth {
break
}
}
}
Essayez ceci son travail pour moi (Swift 3.0)
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// bla bla ... anything inside method you want to do
// reset font size of textfield
textField.font = UIFont.systemFont(ofSize: CGFloat(15.0))
var widthOfText: CGFloat = textField.text!.size(attributes: [NSFontAttributeName: textField.font!]).width
var widthOfFrame: CGFloat = textField.frame.size.width
// decrease font size until it fits (25 is constant that works for me)
while (widthOfFrame - 25) < widthOfText {
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
}
return true
}
-(BOOL)sizeFontToFit:(NSString*)aString minSize:(float)aMinFontSize maxSize:(float)aMaxFontSize
{
float fudgeFactor = 16.0;
float fontSize = aMaxFontSize;
self.font = [self.font fontWithSize:fontSize];
CGSize tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight);
CGSize stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
while (stringSize.height >= self.frame.size.height)
{
if (fontSize <= aMinFontSize) // it just won't fit
return NO;
fontSize -= 1.0;
self.font = [self.font fontWithSize:fontSize];
tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight);
stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
}
return YES;
}
Mon humble solution à ce problème était la suivante ... (trouver moi-même la taille de police appropriée - à la taille du cadre) je l’ai intégrée à la méthode déléguée de shouldChangeCharactersInRange: replacementString:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// bla bla ... anything inside method you want to do
// reset font size of textfield
textField.font = [FONT_PROXY fontNormalOfSizeNormal];
CGFloat widthOfText = [textField.text sizeWithAttributes:@{NSFontAttributeName:textField.font}].width;
CGFloat widthOfFrame = textField.frame.size.width;
// decrease font size until it fits (25 is constant that works for me)
while((widthOfFrame - 25) < widthOfText){
CGFloat fontSize = textField.font.pointSize;
textField.font = [textField.font fontWithSize:fontSize - 0.5f];
widthOfText = [textField.text sizeWithAttributes:@{NSFontAttributeName:textField.font}].width;
widthOfFrame = textField.frame.size.width;
}
}
J'ai eu ce même problème avec UITextFields créé dans StoryBoard dans Xcode 5.0.2, exécutant iOS 7.0.4. J'ai compris que StoryBoard, viewDidLoad ou viewWillAppear ne pouvaient pas modifier la propriété .minimumFontSize, mais qu'elle pouvait était modifiée dans viewDidAppear. Donc, le code suivant a résolu mon problème:
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.myTextField.minimumFontSize = 4.0;
[self.myTextField setNeedsLayout];
[self.myTextField layoutIfNeeded];
}
Testé avec XCode8 et 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
}
}
}
J'ai utilisé viewDidLayoutSubviews pour obtenir tous les champs de texte et pour rétracter automatiquement le texte.
Peut-être que quelqu'un aura besoin de ce code.
Pour moi cela fonctionne parfaitement.
Le code provient de @ Marek Manduch sur ce site et de
@Kunal Kumar sur ce site: Comment obtenir tous les champs de texte depuis une vue dans Swift