この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
テキストを装飾するNSAttributedStringは文字の表現が豊かになり便利な反面、(個人の主観ですが) 記法がすこし面倒です。
今回はそんなNSAttributedStringが書きやすくなるSwiftyAttributesといういライブラリを試してみました。ライセンスはMITです。
https://github.com/eddiekaiger/SwiftyAttributes
検証環境
今回は下記環境で試しています。
Xcode | 8.2 |
---|---|
Swift | 3.0.2 |
CocoaPods | 1.0.0 |
準備
CocoaPodsで追加します。
use_frameworks!
target "ターゲット名"
pod 'SwiftyAttributes'
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |configuration|
configuration.build_settings['SWIFT_VERSION'] = "3.0"
end
end
end
文字を装飾する
簡単な使い方
SwiftyAttributesではStringの拡張として各種装飾のプロパティが用意されています。
下記は文字の色を赤にする例です。(各種装飾はwith○○形式で定義されています)
"対象となる文字列".withTextColor(.red)
複数
複数のAttributeを適用したい場合はつなげて記述します。
例として、下記は文字を赤くして斜めにして青い下線を引いています。
"対象となる文字列".withTextColor(.red).withObliqueness(0.8).withUnderlineStyle(.styleSingle).withUnderlineColor(.blue)
サンプル
各種効果を適用させてみました。
let baseText = "吾輩は猫である"
// フォント .withFont(UIFont)
sample1Label.attributedText = baseText.withFont(UIFont.boldSystemFont(ofSize: 24.0))
// 文字色 .withTextColor(UIColor)
sample2Label.attributedText = baseText.withTextColor(.orange)
// 背景色 .withBackgroundColor(UIColor)
sample3Label.attributedText = baseText.withBackgroundColor(.cyan)
// カーニング .withKern(Double)
sample4Label.attributedText = baseText.withKern(8.0)
// 影 .withShadow(NSShadow)
let shadow = NSShadow.init()
shadow.shadowOffset = CGSize(width: 3, height: 3)
shadow.shadowColor = UIColor.orange // 影の色
shadow.shadowBlurRadius = 4.0 // ぼかしの半径
sample5Label.attributedText = baseText.withShadow(shadow)
// 横に拡大? .withExpansion(Double)
sample6Label.attributedText = baseText.withExpansion(0.8)
// ななめ化 .withObliqueness(Double)
sample7Label.attributedText = baseText.withObliqueness(0.8)
// 線 .withStrokeWidth(Double).withStrokeColor(UIColor)
sample8Label.attributedText = baseText.withStrokeWidth(1.0).withStrokeColor(.blue)
// 下線 .withUnderlineStyle(NSUnderlineStyle).withUnderlineColor(UIColor)
sample9Label.attributedText = baseText.withUnderlineStyle(.styleDouble).withUnderlineColor(.magenta)
// 取り消し線 .withStrikethroughStyle(NSUnderlineStyle).withStrikethroughColor(UIColor)
sample10Label.attributedText = baseText.withStrikethroughStyle(.styleSingle).withStrikethroughColor(.red)
// 段落スタイル .withParagraphStyle(NSMutableParagraphStyle)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
sample11Label.attributedText = baseText.withParagraphStyle(paragraphStyle)
// 文字の方向 .withWritingDirections([WritingDirection])
sample12Label.attributedText = baseText.withWritingDirections([.rightToLeftOverride])
// リンク .withLink(URL)
sample13TextView.attributedText = baseText.withLink(URL(string: "https://classmethod.jp/")!)
まとめて適用するケース
装飾をまとめて適用する場合は.withAttributes([Attribute])形式で記載する方が便利かもしれません。 SwiftyAttributesではAttributeというenumが定義されており、そのリストを定義することが出来ます。
たとえば、
"対象となる文字列".withTextColor(.red).withObliqueness(0.8).withUnderlineStyle(.styleSingle).withUnderlineColor(.blue)
は
"対象となる文字列".withAttributes([.textColor(.red), .obliqueness(0.8), .underlineStyle(.styleSingle), .underlineColor(.blue)])
のように記述することが出来ます。
サンプル
複数の文字に同じ装飾を適用しています。
let attributes: [Attribute] = [.textColor(.white), .backgroundColor(.darkGray), .underlineStyle(.styleDouble), .underlineColor(.magenta)]
sample1Label.attributedText = "Hello World".withAttributes(attributes)
sample2Label.attributedText = "Bonjour le monde".withAttributes(attributes)
sample3Label.attributedText = "Ciao mondo".withAttributes(attributes)
AttributedStringをつなげる
SwiftyAttributesではNSAttributedString + NSAttributedStringのオペレーターが定義されています。
そのため、 + で装飾文字列をつなげることができます。
サンプル
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "cat")
attachment.bounds = CGRect(x: 0, y: -2, width: 16, height: 16)
sampleLabel.attributedText = "吾輩は".withTextColor(UIColor.brown) + NSAttributedString(attachment: attachment) + "である".withTextColor(UIColor.brown)
さいごに
今回、検証してみてSwiftyAttributesを使ったwithLigaturesとwithAttachmentの適用が自分の環境では上手くいきませんでした。(ligaturesの方はフォントが合字に対応していなかったのかもしれません・・・)
attachmentの方は「AttributedStringをつなげる」のサンプルに記載したように+でつなげるのであれば問題ありませんでした。念のため、ご留意ください。