web-dev-qa-db-fra.com

Centrer verticalement deux polices de tailles différentes dans une chaîne NSAttributedString

J'utilise NSAttributedString pour générer une chaîne avec deux tailles différentes. Par défaut, son alignement inférieur ressemble à ceci:

baseline aligned sizes

Mais je veux le centrer verticalement, comme ceci: vertically centered sizes

Pour être clair, il s'agit d'une seule chaîne attribuée, pas de deux ou plus. Ceci est un exemple simplifié pour décrire ma question, ce que j'aimerais vraiment faire est plus complexe.

53
user2608857

Je dirais que la chose la plus simple à faire est simplement de manipuler l'attribut NSBaselineOffsetAttributeName pour le texte en question:

NSBaselineOffsetAttributeName

La valeur de cet attribut est un objet NSNumber contenant une valeur à virgule flottante indiquant le décalage du caractère par rapport à la ligne de base, en points. La valeur par défaut est 0.

Pour centrer, vous devez prendre la différence entre la hauteur du grand texte et la hauteur du texte plus petit et le diviser par deux, puis l'utiliser comme ajustement de ligne de base.

84
Ben Lachman

Voici un exemple de travail pour aligner verticalement un texte plus petit à l'aide de NSBaselineOffsetAttributeName.

NSString *bigString   = @"BIG";
NSString *smallString = @"Small String";
NSString *fullString = [NSString stringWithFormat:@"%@ %@", bigString, smallString];

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:fullString];

NSRange bigStringRange = NSMakeRange(0, bigString.length);
NSRange smallStringRange = NSMakeRange(bigStringRange.length, smallString.length);

[string beginEditing];


//Set big string font and size
[string addAttribute:NSFontAttributeName
               value:[UIFont systemFontOfSize:28.0]
               range:bigStringRange];

//set small string font and size
[string addAttribute:NSFontAttributeName
               value:[UIFont systemFontOfSize:18.0]
               range:smallStringRange];

//Set small string baseline offset
[string addAttribute:NSBaselineOffsetAttributeName
               value:[NSNumber numberWithFloat:3.0]  //adjust this number till text appears to be centered
               range:smallStringRange];

[string endEditing];
23
Yas T.

réponse de YasT dans Swift:

Swift 4

let bigString = "BIG"
let smallString = "Small String"
let fullString = "\(bigString) \(smallString)"
let string = NSMutableAttributedString(string: fullString)

let bigStringRange = NSRange(location: 0, length: bigString.utf16.count)
let smallStringRange = NSRange(location: bigStringRange.length + 1, length: smallString.utf16.count)

let bigStringFontSize: CGFloat = 28
let smallStringFontSize: CGFloat = 18

string.beginEditing()

string.addAttribute(.font, value: UIFont.systemFont(ofSize: bigStringFontSize), range: bigStringRange)
string.addAttribute(.font, value: UIFont.systemFont(ofSize: smallStringFontSize), range: smallStringRange)
string.addAttribute(.baselineOffset, value: (bigStringFontSize - smallStringFontSize) / 2, range: smallStringRange)

string.endEditing()

Swift 3

let bigString = "BIG"
let smallString = "Small String"
let fullString = "\(bigString) \(smallString)"
let string = NSMutableAttributedString(string: fullString)

let bigStringRange = NSRange(location: 0, length: bigString.utf16.count)
let smallStringRange = NSRange(location: bigStringRange.length + 1, length: smallString.utf16.count)

let bigStringFontSize: CGFloat = 28
let smallStringFontSize: CGFloat = 18

string.beginEditing()

string.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: bigStringFontSize), range: bigStringRange)
string.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: smallStringFontSize), range: smallStringRange)
string.addAttribute(NSBaselineOffsetAttributeName, value: (bigStringFontSize - smallStringFontSize) / 2, range: smallStringRange)

string.endEditing()
4
Tamás Sengel

Une meilleure solution consiste à calculer NSBaselineOffsetAttributeName à partir de la typographie des polices (court article https://www.raizlabs.com/dev/2015/08/advanced-ios-typography/ )

Définissez l'attribut pour la deuxième partie de la chaîne attribuée.

secondPartAttributes[NSBaselineOffsetAttributeName] = @((firstFont.xHeight - secondFont.xHeight)/2);
3
Raman