iOSでのテキストスタイリング: カーニング(Kerning)ポイント(Styling Text on iOS: The Kerning Point)

[Original Link](https://bytes.blueapron.com/styling-text-on-ios-the-kerning-point-b373cabfaca5 "Original Link")
by [Rob Huebner](https://twitter.com/huebnerob)
translated Korean by [pilgwon](https://pilgwon.github.io)

![1*SlXUBtDz7qV3Y5qHyauMcg.jpeg](https://qiita-image-store.s3.amazonaws.com/0/100829/82e5cd4b-045b-430d-8fea-0605a5154748.jpeg)

他に注目するほどのことがない水曜の朝に、Slackのアラートに沈黙は破られた。それはデザイン担当だった。彼はうちのフォントにちょっとした修正可否を訪ねてきた。"はい、そしてうちのすべてのトラッキング(tracking)もちょっとずつ修正する必要があるようです"

##基本的な属性
このリクエストがなぜでっかい仕事なのか理解するため、iOSでテキストを見せてくれるに一番基本的な方法である```UILabel```を利用してみましょう。

もしあなたが作業するところに```UIKit```を利用するのであれば、```UILabel```に関するよく知っていると思います。これは些細なUIをカスタマイズ可能な属性である```font```、```textColor```、そして```textAlignment```の属性を持っています。しかしその後貴方は壁にぶつかり始めることになると思います。ある格好いい作業をするためには普通テキストとそれにふさわしい適切な属性を持っている```NSAttributedString```が必要になり、```label```の```attributedText```属性を利用します。

それは良さげに見えますがこのやり方を拡張するなり、他の方法を考えて見ると:

* attributedStringを作るのは結構ごつくて不必要に見えます。
* labelのテキストが動的であれば、スタイルが変わっていないとしても貴方はすべての```attributedString```をテキストに変更するたびに新たに実装しないといけません。
* 文字列のスタイルを標準化したり、デフォルト値を元で構築する方法は存在しません。
トラッキングあるいはカーニング(アップルはこう呼んでます)は```attributedString```で飲み使えるパラメーターの一つです。なので、もしフォントのカーニングを全体的に調整するためにはtextの代わりに```attributedText```を全体的に使う必要があります。ただ、これは結構コード複雑度を招く恐れがあります。

![1*XpyCzxnwA1SuV0Q_vFvsdA.png](https://qiita-image-store.s3.amazonaws.com/0/100829/8ae9a979-b026-ab2d-202a-d13f69f7deb9.png)

ではもっと良さげなフォントシステムを作ってみましょ。

##テキストスタイル
attributed stringを必要なすべての箇所に手動で追加する作業は本当にやりたくありませんでした。
静的テキストスタイルはテキスト自体とは独立的に宣言するのがいいと思います。そうすると、labelのライフサイクルを早い段階でスタイルが設定でき、後からは考えなくてもよくなります。

そのため、iOSの宣言的なテキストスタイリングライブラリーである```StyledText```を実装しました。```StyledText```は二つのコンセプトを説明します。: ```TextStyle```, 特定テキストスタイルパラメーターセットを表すタイプ; そしてスタイルを受け入れてテキスト内容を描く時に利用するUIViewのサブクラスであるStyled. ただTextSTyleを上に実装して、```StyledLabel```に送れば終わりです:

```swift
class ViewController: UIViewController {
    private let styledLabel: StyledLabel = {
        let label = StyledLabel(frame: .zero)
        label.textStyle = TextStyle(font: .systemFont(ofSize: 14),
                                   color: .blue,
                             lineSpacing: 4.0,
                                    kern: 1.5)
        return label
    }()

    func updateLabel() {
        styledLabel.text = "This is a simple string"
    }
}
```

##実用性あるデフォルト値
前に出ていたのは素晴らしいですが、まだ結果的にすべての問題を解決はできておりません。どうやってアプリのカーニングの調整をすればよろしいでしょうか。その答えは```TextStyle```にあります。ここでは```TextStyleDefaultsGenerator```と名付けます。この中で一つ設定を行えばスタイルは指定されていないまま初期化されるたびにカーニングのデフォルト値を設定できます。

```swift
extension TextStyle: TextStyleDefaultsGenerator {
    private static let defaultCeraKern: CGFloat = -0.2
    private static let defaultChronicleKern: CGFloat = -0.2
    static public func defaultKern(for font: UIFont) -> CGFloat? {
        if font.fontName.contains("Cera") {
            return defaultCeraKern
        } else if font.fontName.contains("Chronicle") {
            return defaultChronicleKern
        }
        return nil
    }
}
```

問題解決. 😎

Blue Apron iOS アプリに TextStyleを適用してからフォントはどこからでも詳細の内容まで設定が可能になり、オーバーヘッドの負担も少なくなります。そして```StyledText```をオープンソースライブラリーでiOSコミュニティに公開することになりました。続けて修正されれモバイルプラットフォームに役に立つ強いタイプグラプィツールになれば嬉しいと思います。


##ボーナス: 自然な接近が勝ちます！
我々はすべてのテキストスタイリングを中央集中式にて実装していて対応可能な機能は多いと思います。例えば、ユーザーがそれらのシステムフォントサイズを変更可能にするアップルのツールである動的フォントサイズに対応が可能になります。```StyledText```のすべての含まれているのはすべての```TextStyle```に動的にフォントサイズを指定できる機能です。:
![埋め込み](https://cdn-images-1.medium.com/max/800/1*b3ytduAfQ3Rn2k_o4VdyLQ.gif)

##貴方のテキストを作り上げて見てください

[GitHubにあるREADME](https://github.com/blueapron/styled-text)をご確認ください! Contributeも積極的に受け入れます。

[ * ] タイプグラプィは実際、 “カーニング(kerning)”をふた文字の間の空間で定義します。. 例えば、 ‘A’と ‘V’の模様は重ねることができるため多くのフォントで近くついてします。. “トラッキング(Tracking)”はもっと大きい任意の文字列に関して文字間隔の調整を見せてくれます。. ただアップルは文字列属性の ```NSKernAttributeName```で前の２つの概念を提供してくれるのえ```StyledText```も同じであります。