web-dev-qa-db-ja.com

NSAttributedStringで異なるサイズの2つのフォントを垂直方向に中央揃え

NSAttributedStringを使用して、2つの異なるサイズの文字列を生成します。デフォルトでは、下部の配置は次のようになります。

baseline aligned sizes

ただし、次のように垂直方向に中央に配置します。 vertically centered sizes

明確にするため、これは単一の属性付き文字列であり、2つ以上ではありません。これは私の質問を説明するための簡単な例です。実際にやりたいことはもっと複雑です。

53
user2608857

最も簡単なことは、問題のテキストのNSBaselineOffsetAttributeName属性を操作することです。

NSBaselineOffsetAttributeName

この属性の値は、ベースラインからの文字のオフセットをポイントで示す浮動小数点値を含むNSNumberオブジェクトです。デフォルト値は0です。

中央に配置するには、大きなテキストの高さと小さなテキストの高さの差を取り、それを半分にしてから、ベースライン調整として使用します。

84
Ben Lachman

以下は、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.

YasTの答え 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

より良い解決策は、フォントのタイポグラフィからNSBaselineOffsetAttributeNameを計算することです(短い記事 https://www.raizlabs.com/dev/2015/08/advanced-ios-typography/

属性付き文字列の2番目の部分の属性を設定します。

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