web-dev-qa-db-ja.com

NSMutableAttributedString範囲に太字と斜体を適用する方法は?

私は最近、NSFontAttributesの組み合わせをNSMutableAttributedStringに適用しようとしていますが、他の属性を削除せずにそれを行う方法についての完全な説明を見つけることができません。

私はたくさん検索しましたが、これは question でHTMLを使用する方法に関するもので、次に questionfindテキストは太字または斜体になっていますが、実際にそれを行う方法については何もありません。

現在、私は文字列を次のようにフォーマットしようとしています:

斜体:[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が含まれていないため、これがフォーマットを実行する正しい方法であってはならないことを知っていますが、これを行う適切な方法を見つけることができません。誰か助けてもらえますか?

14
Micrified

各(太字または斜体)特性を個別に適用する場合は、太字と斜体の範囲が重複しないようにする必要があります。そうしないと、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))

enter image description here

7
user4151918

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()) ])
}
20
nyg

これまでの私の問題に対する最善の解決策は、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

ここでの利点は、個々のフォントタイプを自分で作成する必要がなくなり、ファミリのフォントで作成できることです。

8
Micrified

チェックアウト NSAttributedString.Key.obliqueness。このキーの値を0以外の値に設定すると、テキストの斜体の度合いが異なります。

2
qsmy

細部

  • Swift 5.1、Xcode 11.3.1

解決

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)
    }
}

結果

enter image description here

0