私は最近、NSFontAttributesの組み合わせをNSMutableAttributedStringに適用しようとしていますが、他の属性を削除せずにそれを行う方法についての完全な説明を見つけることができません。
私はたくさん検索しましたが、これは question でHTMLを使用する方法に関するもので、次に question でfindテキストは太字または斜体になっていますが、実際にそれを行う方法については何もありません。
現在、私は文字列を次のようにフォーマットしようとしています:
斜体:[mutableAttributedString addAttribute: NSFontAttributeName value:[fontAttributes valueForKey:CXItalicsFontAttributeName] range:r];
太字:[mutableAttributedString addAttribute:NSFontAttributeName value:[fontAttributes valueForKey:CXBoldFontAttributeName] range:r];
定数CXItalicsFontAttributeName
およびCXBoldAttributeName
は、辞書から次の2つの値をそれぞれ抽出します。
UIFont *italicsFont = [UIFont fontWithName:@"Avenir-BookOblique" size:14.0f];
UIFont *boldFont = [UIFont fontWithName:@"Avenir-Heavy" size:14.0f];
NSAttributedString 標準の属性 にItalicsFontAttributeまたはBoldFontAttributeが含まれていないため、これがフォーマットを実行する正しい方法であってはならないことを知っていますが、これを行う適切な方法を見つけることができません。誰か助けてもらえますか?
各(太字または斜体)特性を個別に適用する場合は、太字と斜体の範囲が重複しないようにする必要があります。そうしないと、1つの特性が他の特性を上書きします。
太字との両方の斜体特性を範囲に適用する唯一の方法は、太字と斜体の両方のフォントを使用して、両方の特性を一度に適用することです。
let str = "Normal Bold Italics BoldItalics"
let font = UIFont(name: "Avenir", size: 14.0)!
let italicsFont = UIFont(name: "Avenir-BookOblique", size: 14.0)!
let boldFont = UIFont(name: "Avenir-Heavy", size: 14.0)!
let boldItalicsFont = UIFont(name: "Avenir-HeavyOblique", size: 14.0)!
let attributedString = NSMutableAttributedString(string: str, attributes: [NSFontAttributeName : font])
attributedString.addAttribute(NSFontAttributeName, value: boldFont, range: NSMakeRange(7, 4))
attributedString.addAttribute(NSFontAttributeName, value: italicsFont, range: NSMakeRange(12, 7))
attributedString.addAttribute(NSFontAttributeName, value: boldItalicsFont, range: NSMakeRange(20, 11))
Swiftおよび拡張機能を使用して:
extension UIFont {
func withTraits(_ traits: UIFontDescriptorSymbolicTraits) -> UIFont {
// create a new font descriptor with the given traits
guard let fd = fontDescriptor.withSymbolicTraits(traits) else {
// the given traits couldn't be applied, return self
return self
}
// return a new font with the created font descriptor
return UIFont(descriptor: fd, size: pointSize)
}
func italics() -> UIFont {
return withTraits(.traitItalic)
}
func bold() -> UIFont {
return withTraits(.traitBold)
}
func boldItalics() -> UIFont {
return withTraits([ .traitBold, .traitItalic ])
}
}
例:
if let font = UIFont(name: "Avenir", size: 30) {
let s = NSAttributedString(string: "Hello World!", attributes: [ NSFontAttributeName: font.italic() ])
let t = NSAttributedString(string: "Hello World!", attributes: [ NSFontAttributeName: font.boldItalic()) ])
}
これまでの私の問題に対する最善の解決策は、UIFontDescriptor
クラスを使用して、遭遇する各ケースに必要なUIFont
を提供することです。
たとえば、Avenir-Book
をサイズ14
のプライマリフォントとして使用したいので、次のようにUIFontDescriptor
を作成できます。
UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:@"Avenir-Book" size:14.0f];
次に、斜体、太字、または両方の組み合わせを取得したい場合は、次のように簡単に実行できます。
NSString *normalFont = [[fontDescriptor fontAttributes]valueForKey:UIFontDescriptorNameAttribute];
NSString *italicsFont = [[[fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic]fontAttributes]valueForKey:UIFontDescriptorNameAttribute];
NSString *boldFont = [[[fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold]fontAttributes]valueForKey:UIFontDescriptorNameAttribute];
NSString *boldAndItalicsFont = [[[fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold | UIFontDescriptorTraitItalic]fontAttributes]valueForKey:UIFontDescriptorNameAttribute];
そして、これは実際に印刷時に必要なフォントを生成します:
NSLog(@"Normal Font: %@ Size: %@\n",normalFont,[[fontDescriptor fontAttributes]valueForKey:UIFontDescriptorSizeAttribute]);
NSLog(@"Italics Font: %@\n",italicsFont);
NSLog(@"Bold Font: %@\n",boldFont);
NSLog(@"Bold and Italics Font: %@\n",boldAndItalicsFont);
出力:
Normal Font: Avenir-Book Size: 14
Italics Font: Avenir-BookOblique
Bold Font: Avenir-Black
Bold and Italics Font: Avenir-BlackOblique
ここでの利点は、個々のフォントタイプを自分で作成する必要がなくなり、ファミリのフォントで作成できることです。
チェックアウト NSAttributedString.Key.obliqueness
。このキーの値を0以外の値に設定すると、テキストの斜体の度合いが異なります。
extension UIFont {
class func systemFont(ofSize fontSize: CGFloat, symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFont? {
return UIFont.systemFont(ofSize: fontSize).including(symbolicTraits: symbolicTraits)
}
func including(symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFont? {
var _symbolicTraits = self.fontDescriptor.symbolicTraits
_symbolicTraits.update(with: symbolicTraits)
return withOnly(symbolicTraits: _symbolicTraits)
}
func excluding(symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFont? {
var _symbolicTraits = self.fontDescriptor.symbolicTraits
_symbolicTraits.remove(symbolicTraits)
return withOnly(symbolicTraits: _symbolicTraits)
}
func withOnly(symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFont? {
guard let fontDescriptor = fontDescriptor.withSymbolicTraits(symbolicTraits) else { return nil }
return .init(descriptor: fontDescriptor, size: pointSize)
}
}
font = UIFont.italicSystemFont(ofSize: 15).including(symbolicTraits: .traitBold)
font = UIFont.systemFont(ofSize: 15, symbolicTraits: [.traitBold, .traitItalic])
font = font.excluding(symbolicTraits: [.traitBold]
font = font.withOnly(symbolicTraits: [])
ここにソリューションコードを貼り付けることを忘れないでください。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
addLabel(Origin: .init(x: 20, y: 20), font: .systemFont(ofSize: 15, symbolicTraits: [.traitBold, .traitItalic]))
addLabel(Origin: .init(x: 20, y: 40), font: UIFont.italicSystemFont(ofSize: 15).including(symbolicTraits: .traitBold))
guard let font = UIFont.systemFont(ofSize: 15, symbolicTraits: [.traitBold, .traitItalic]) else { return }
addLabel(Origin: .init(x: 20, y: 60), font: font.excluding(symbolicTraits: [.traitBold]))
addLabel(Origin: .init(x: 20, y: 80), font: font.withOnly(symbolicTraits: []))
}
private func addLabel(Origin: CGPoint, font: UIFont?) {
guard let font = font else { return }
let label = UILabel(frame: .init(Origin: Origin, size: .init(width: 200, height: 40)))
label.attributedText = NSAttributedString(string: "Hello World!", attributes: [.font: font, .foregroundColor: UIColor.black ])
view.addSubview(label)
}
}