絶品ゆどうふのタレ

ふと気づいたことを綴るだけのメモ

iOSDC Japan 2016 参加メモ: A-1 - Handling rich text in Swift

  • Realm 岸川さん

何も考えずにiOSのテキストを作ると、色々ずれてたり、切れてたりしてしまう。

デザイナさんはここを直してほしい、というけどiOSのラベルでは難しい、とか、そういう状況をなくしていくためにTextを理解しよう。

アジェンダ

TextKit

  • iOS7から導入
    • CoreTextをベースに作られている
    • UIKItとの統合
    • UILabel / UITextView などのベース

UILabel

  • ヒラギノとシステムフォント
  • system font

    • 英字はsanfrancisco
    • 日本語はヒラギノにフォールバック
  • 明示的にヒラギノを指定したりすると、英字もヒラギノになり、ベースラインより下にはみ出るものが切れてしまったりする

    • 日本語ははみ出る文字がないので無事だが。。。
  • 中身のテキストによって切れてしまう。

なぜこんなことが起こるのか?

  • 行の高さを知る

    • アルファベットのFontのお話
    • BaselineやCap height、Ascent、Descent、x-heightなど
    • これらのFont metricsによって高さが決まる
  • systemfontは、これらが全体にだいたい収まるようになっている

  • ヒラギノは特殊なメトリクスを持つ

    • Ascent Descentが狭い(半分ずつ)
    • Noto Sans CJK なんかだと大丈夫だたりする
  • バッドノウハウ

    • 上下にDescentを補う
      • Descentを倍にする

いったんまとめ

  • ヒラギノのメトリクスに注意

    • 明示的にヒラギノを指定しない
    • システムフォントを使う
      • ヒラギノ指定のデザインは、システムフォントを意図しているはず
      • 中国語フォントにフォールバックさせたくない、とか。
    • ヒラギノを指定する場合にはアルファベットに注意
  • Tips 日本語フォントにフォールバックを指定することはできる

  • Tips

    • 描画サイズを得る
    • iOS7からならできる

UITextView

  • 普通につかう

    • ヒラギノを指定すると、だいぶ大きくなったりする
  • TextViewにはデフォルトのマージンがある

    • textContainerInset
    • lineFragmentPadding
    • ヒラギノの場合は font.leadingという値のぶん高さがついてくる

デフォルトのスタイルをリセットする

textView.textContainerInset = UIEdgeInsetsZero
textView.textContainer.lineFragmentPadding = 0
textView.layoutManager.usesFontLeading = false // leadingを取り除く
  • ドキュメントには、UIに使うときはleadingはoffにすると良いよって書いてある
  • leadingを含めた描画サイズをオプションを指定することで取ることもできる

これを元に様々なスタイルに対応する

  • 行間の変更

    • NSAttributedString
    • NSParagraphStyle
      • minimumLineHeight
      • maximumLineHeight
        • これを同一にすると行の高さが一致する
        • これらは、複数のフォントサイズが混在する文章のためにある
      • lineSpacing = 8
  • NSAttributedStringを活用する

まとめ

  • iOS7 以降はいかに綺麗なNSAttributedStringを作るか
  • タイポグラフィの基礎を知ろう
  • フォントにヒラギノを指定するときは注意
  • できればシステムフォントに

QA

  • システムフォントは、日本語のヒラギノフォントよりも小さい。これをデザイナに指摘される場合どうするか
    • デザイナの人と共有・コンセンサスを取るのがいいのでは
    • たぶん、MacヒラギノとSanfranciscoは、同じサイズになるのでは。。。