Helvetica Neueは数値が等幅

まえがき

先日、動画アプリを作った。

randomtube-screenshot.jpg

シークバーは上のように、左右に経過時間と合計時間がそれぞれ表示されるようになっている。 経過時間(左時間ラベル)の最大幅はその動画の合計時間の幅にしていて、 例えば 1:23:45 の動画なら 現在時刻が 0:00 だとしても 1:23:45 の幅を維持されるようになる。

なぜ時間幅を単純に Auto Layout で指定しないのかというと、 もし経過時間によってラベル幅が動的に変わってしまうと、シークバーの幅も変わり、 つまみを動かしている時につまみがガタガタ動いてしまって目的の位置までスライドできないからだ。

問題

iOS9になってから、この左の経過時間ラベルの表示がおかしくなった。

例えば「1:23」という表示が「1:...」のように省略されるようになってしまった。

原因

これは、iOS 8 までで使われていた Helvetica Neue で通用していた経過時間の最大幅の決定方法が、 iOS 9から新たにシステムフォントとなった San Francisco では通用しなくなったのが原因だ。

Helvetica Neue はプロポーショナルフォントだが、数値だけは等幅だ。 その為、例えば1:23:45の最大幅を決める為に、どの文字が一番大きいかなど考える必要がなく、 単に1:23:45を最大幅と考えることが出来た。

一方 San Francisco では、数値もプロポーショナルフォントとなっている。 しかも、サイズと太さの組み合わせによって、0が一番大きかったり8が一番大きかったりする。

その為、もし0が一番大きい場合、合計時間が 1:23:45 なら 00:00:00 の文字幅を取れば良い。

そもそも San Francisco ほどに違わないとしても、数値がプロポーショナルフォントというのは 全く珍しくない。デザイン重視のAppleが一般ユーザーの目に触れるフォントとして採用していた フォントが等幅だった方が変だったと思う。

でも無印Helveticaでさえ1だけは幅が狭いので、あえて等幅が選ばれた理由は何かあるっぽい。

解決方法

  1. Helvetica Neueにする

    一番楽な解決方法。

    でも一般ユーザーの目に触れるものを等幅にしたくない。 また、San Franciscoは時間を表す時に使う「:」の位置も前後の文字によって動的に変わったりと、表示の美しさにこだわってるのでなるべくそっちを使いたい。

    なので却下。

  2. San Franciscoの等幅モードを使う

    UIFont には + monospacedDigitSystemFontOfSize:weight: というメソッドがあり、San Francisco でも等幅になる。

    ただ、太さによってはこのメソッドが効かないとかいう話があったりするし、 IBの設定だけで有効には出来ないし、アルファベットまで等幅になるし、そもそも等幅は嫌だしで却下。

  3. 一番幅広の文字をあらかじめ調べてハードコーディングしておく

    柔軟性は無いが、フォントサイズがあらかじめ分かっていて、そのフォントが動的に変わるわけでなければこれで十分。

    今回はこれにした。

  4. サイズと太さによって数値文字の幅を動的に決定する

    NSString- sizeWithAttributes:で一番幅広の文字を探しておき、それを使う。

    多少のコードが必要になるがフォントの変更に柔軟に対応できる。