【Swift4】NSAttributedStringでUILabelやUITextFieldのテキストを装飾する方法

## NSAttributedStringとは

`NSAttributedString` とは、 `UILabel` や`UITextField` のテキスト（文字列）を装飾するためのクラスです。
フォントの種類やサイズはもちろん、行間や縁取りなど、いろいろな要素を指定できます。

## NSAttributedStringの使いかた

NSAttributedStringでテキストを装飾する場合は、 `NSAttributedStringクラス` のinit処理 `init(string:attributes:)` をつかいます。

[アップル公式リファレンス](https://developer.apple.com/documentation/foundation/nsattributedstring "NSAttributedString")によると、 `Returns an NSAttributedString object initialized with a given string and attributes.` とのことなので、テキスト（String）と属性（attributes）をわたすことで、NSAttributedStringオブジェクトを返してくれます。

それでは、init処理の使いかたを見ていきましょう。

### 装飾する属性を設定する

まず、装飾する属性（attributes）を設定します。

```Swift
        let textAttributes: [NSAttributedStringKey : Any] = [
            .font : UIFont.systemFont(ofSize: 24.0),
            .foregroundColor : UIColor.green,
            .strokeColor : UIColor.red,
            .strokeWidth : -3.0
        ]
```

attributesは `[NSAttributedStringKey : Any]` のDictionary型です。

[NSAttributedStringKey](https://developer.apple.com/documentation/foundation/nsattributedstringkey "NSAttributedStringKey")は属性の名前です。
たとえば、フォントを設定する属性は `font` 、縁取りの色を設定する属性は `strokeColor` というようにあらかじめ名前が決まっています。このNSAttributedStringKeyを指定することで、自分が設定したい属性を指定することができます。

`Any` には、NSAttributedStringKeyに対応する値を指定します。
たとえば、NSAttributedStringKeyに `font` を指定した場合は、 `UIFont.systemFont(ofSize: 24.0)` のように、フォントに関する情報を指定します。

また、attributesはDictionary型なので、複数の属性を指定することができます。

### テキストと属性をinitに渡してNSAttributedStringオブジェクトをつくる

つぎに、NSAttributedStringオブジェクトをつくります。

```Swift
        let text = NSAttributedString(string: "Lorem ipsum dolor sit er elit lamet", attributes: attributes)
```

第一引数の `string` には、装飾したいテキストを設定します。
第二引数の `attributes` には、さきほどつくった属性の `textAttributes` を設定します。

これで、 `text` に `NSAttributedStringオブジェクト` が代入されました。

### NSAttributedStringオブジェクトをattributedTextプロパティに代入する

最後に、装飾した `NSAttributedStringオブジェクト` を `attributedTextプロパティ` に代入します。

```Swift
        textView.attributedText = text
```

UILabelやUITextViewにテキストを表示するときは、 `textプロパティ` に代入します。しかし、装飾したテキストを表示するときは `attributedTextプロパティ` に代入する必要があるので注意してください。

### サンプルプログラム全文

上で紹介したサンプルプログラムの全文を載せます。

```Swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textView: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        attributed()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func attributed() {
        let style = NSMutableParagraphStyle()
        style.lineSpacing = 6
        let textAttributes: [NSAttributedStringKey : Any] = [
            .font : UIFont.systemFont(ofSize: 24.0),
            .paragraphStyle : style,
            .foregroundColor : UIColor.green,
            .strokeColor : UIColor.red,
            .strokeWidth : -3.0
        ]
        let text = NSAttributedString(string: "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda.", attributes: textAttributes)
        textView.attributedText = text
    }   
}
```

実行すると、このようなテキストが表示されます。

![Attributed01 -3.0.png](https://qiita-image-store.s3.amazonaws.com/0/38924/1bcb6323-5243-5765-186c-5473d65d32db.png)


## strokeWidthについて

文字の縁取りをするときに使用する `strokeWidth` は、設定する数値によって動きが変わります。

上の例のように `.strokeWidth : -3.0` とマイナスを指定すると、縁取りのなかの色は `foregroundColor` で指定した色になります。しかし、 `.strokeWidth : 3.0` のようにプラスを指定すると、下の画像のように `foregroundColor` が無視されるようです。

![Attributed02 3.0.png](https://qiita-image-store.s3.amazonaws.com/0/38924/9c2ed618-5176-6cd1-b363-ea4c8ed6f98d.png)


## NSAttributedStringKeyの一覧

最後に、[NSAttributedStringKey](https://developer.apple.com/documentation/foundation/nsattributedstringkey "NSAttributedStringKey")の一覧を載せます。とてもたくさんあるので、いろいろと試してみてください。

- accessibilityAlignment
- accessibilityAnnotationTextAttribute
- accessibilityAttachment
Text attachment (id).
- accessibilityAutocorrected
Autocorrected text (NSNumber as a Boolean value).
- accessibilityBackgroundColor
Text background color (CGColorRef).
- accessibilityCustomText
- accessibilityFont
Font keys (NSDictionary).
- accessibilityForegroundColor
Text foreground color (CGColorRef).
- accessibilityLanguage
- accessibilityLink
Text link (id).
- accessibilityListItemIndex
- accessibilityListItemLevel
- accessibilityListItemPrefix
- accessibilityMarkedMisspelled
Misspelled text that is visibly marked as misspelled (NSNumber as a Boolean value). If you’re implementing a custom text-editing app, use NSAccessibilityMarkedMisspelledTextAttribute to ensure that VoiceOver properly identifies misspelled text to users.
- accessibilityMisspelled
Misspelled text that isn’t necessarily visibly marked as misspelled (NSNumber as a Boolean value). Beginning in OS X v10.9, VoiceOver no longer checks for this attribute; instead, VoiceOver uses accessibilityMarkedMisspelled.
- accessibilityShadow
Text shadow (NSNumber as a Boolean value).
- accessibilityStrikethrough
Text strikethrough (NSNumber as a Boolean value).
- accessibilityStrikethroughColor
Text strikethrough color (CGColorRef).
- accessibilitySuperscript
Text superscript style (NSNumber). Values > 0 are superscript; values < 0 are subscript.
- accessibilityUnderline
Text underline style (NSNumber).
- accessibilityUnderlineColor
Text underline color (CGColorRef).
- attachment
- backgroundColor
- baselineOffset
- cursor
The value of this attribute is an NSCursor object. The default value is the cursor returned by the 
iBeam method
- expansion
- font
- foregroundColor
- glyphInfo
The name of an NSGlyphInfo object.
- kern
- ligature
- link
- markedClauseSegment
- obliqueness
- paragraphStyle
- shadow
- spellingState
The spelling state attribute.
- strikethroughColor
- strikethroughStyle
- strokeColor
- strokeWidth
- superscript
The value of this attribute is an NSNumber object containing an integer. The default value is 0.
- textAlternatives
- textEffect
- toolTip
The value of this attribute is an NSString object containing the tooltip text. The default value is nil, indicating no tooltip is available.
- underlineColor
- underlineStyle
- verticalGlyphForm
- writingDirection