J'ai UITextField avec un texte plus long défini comme espace réservé. Ce que je veux, c'est que ce texte espace réservé modifie la taille de la police lorsque la largeur du champ est trop petite.
J'ai déjà essayé cette solution décrite dans d'autres articles (par programme et dans IB)
self.fieldTest.adjustsFontSizeToFitWidth = true
self.fieldTest.minimumFontSize = 10.0
Qu'est-ce que j'oublie ici?
Vous pouvez créer une sous-classe de 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
}
}
}
}
Ou vous pouvez simplement ajouter du code dans la variable viewDidAppear
de votre contrôleur de vue:
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
}
}
}
Voici :
_myTextField.placeholder = @"SomeTextSomeTextSome";
UILabel *label = [_myTextField valueForKey:@"_placeholderLabel"];
label.adjustsFontSizeToFitWidth = YES;
À votre santé!!
Voici une solution qui dépend du fait non documenté que la UITextField
a un enfant UILabel
(en fait UITextFieldLabel
) pour rendre l’espace réservé. L'avantage de cette solution par rapport à d'autres solutions est qu'elle se dégrade progressivement si l'implémentation d'Apple devait changer. Cela ne suppose pas non plus l'existence d'ivars non documentés.
Fondamentalement, nous étendons UILabel via une catégorie. Si nous nous voyons parent d'une variable UITextField
, nous activons adjustFontSizeToFitWidth
.
@interface UILabel (TS)
@end
@implementation UILabel (TS)
- (void) didMoveToSuperview
{
[super didMoveToSuperview];
if ( [self.superview isKindOfClass: [UITextField class]] ) {
self.adjustsFontSizeToFitWidth = YES;
}
}
@end
Après avoir examiné la référence de classe pour UITextField, il semble que le fait d’ajusterFontSizeToFitWidth n’affecte que la propriété text de UITextField et non la propriété placeholder. Bien que je ne connaisse pas par cœur un moyen de faire en sorte que le paramètre fictif réponde àjustesFontSizeToFitWidth, je peux vous suggérer deux idées peu recommandables qui peuvent vous donner l'apparence souhaitée. Sachez simplement que je ne suis pas près d'un Mac pour le moment et que je n'ai pas testé ces idées:
1:
Étant donné qu'un espace réservé est juste un texte avec 70% de gris, vous pouvez définir la propriété text de l'étiquette comme vous le souhaitez, puis implémenter la méthode textFieldSelDeegateEdit de UITextFieldDelegate afin qu'elle redevienne normale. . Vous devez également implémenter les méthodes textFieldShouldClear et textFieldDidEndEditing pour remplacer le pseudo-espace réservé dans UITextField et redéfinir la couleur du texte sur 70% de gris.
2:
Dans viewWillAppear, vous pouvez définir le texte de UITextField sur ce que vous souhaitez remplacer, créer un objet UIFont et lui attribuer la même valeur que la propriété de police UITextField, effacer le texte de UITextField et définir le paramètre fictif comme étant un objet NSAttributedString avec l'objet de police comme une propriété. Voici un exemple de ce que je veux dire:
-(void)viewWillAppear:(BOOL) animated {
[super viewWillAppear:animated];
someTextField.adjustsFontSizeToFitWidth = YES;
someTextField.text = @"placeholderText";
UIFont *font = someTextField.font;
someTextField.text = nil;
NSDictionary * attributes = [NSDictionary dictionaryWithObject:color forKey:NSFontAttributeName];
NSAttributedString *placeholderString= [[NSAttributedString alloc] initWithString:@"placeholderText" attributes:attributes];
someTextField.placeholder = palceholderString;
}
Edit: vient de remarquer la balise Swift. J'ai écrit mon code en Objective-C, mais vous devriez pouvoir le traduire facilement en Swift.
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
}
}
}
Rapide
N'hésitez pas à améliorer l'extension. Il est pratiquement certain qu'il existe un moyen plus élégant de parcourir les vues secondaires.
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
}
}
Essayez d'utiliser un espace réservé attribué au lieu d'un espace réservé normal
Essaye ça
let attributedplaceholder = NSAttributedString(string: "placeholdertext", attributes: [NSFontAttributeName: UIFont(name: "FontName", size: 10)!])
self.fieldTest.attributedPlaceholder = attributedplaceholder
Vous pouvez ajouter des attributs supplémentaires à l’espace réservé, comme textcolor et autres.
En rapide
yourTextField.subviews
.filter { $0 is UILabel }
.flatMap { $0 as? UILabel }
.forEach {
$0.adjustsFontSizeToFitWidth = true
$0.minimumScaleFactor = 0.5
}
Ça marche :)
Vous pouvez utiliser ces deux solutions:
1.Si vous avez fixé la taille de la police si la taille du champ de texte est inférieure au texte fictif:
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) Si vous souhaitez une taille de police dynamique, il vous suffit de vérifier la condition ci-dessus pour la largeur du champ de texte et la taille du texte si la taille du texte de l'espace réservé est supérieure à la taille du champ de texte, créez une étiquette à l'intérieur du champ de texte et définissez une police minimale.
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)
}