📐

【SwiftUI】大きさを数字で指定したシステムフォントをDynamic Typeに対応させる

2023/08/12に公開

結論

Text("Hello, world!")
    .font(.custom("", size: 40))

custom っていうのは本来はフォント名を指定するものだが、フォント名を "" にすることでデフォルトのフォントを指定する。

Dynamic Typeの変化の仕方を指定する

デバイスで文字の大きさ(X SmallやAX5など)を変えた時、(基準値と比べて)どう大きくor小さくなるかという変化の仕方に選択肢がある。ざっくり言うと激しく変化するとかまろやかに変化するなどから選べる。これは .title.caption から選ぶ方式である。.title にすると変化の仕方がフォントの .title と同じになる。

ここから大きさに関する2つの軸

  • X Small - Large - AX5という軸。ユーザーがデバイス上で設定する。
  • .caption2 - .body - .largeTitleという軸。開発者がソースコードに書き込む。

を区別するように気をつけてください。

では .largeTitle のように変化するものと、.caption2 のように変化するものを同時に表示したものを載せる。

Text("Hello, world!")
    .font(.custom("", size: 40, relativeTo: .largeTitle))
Spacer()
Text("Hello, world!")
    .font(.custom("", size: 40, relativeTo: .caption2))

.largeTitle は変化がゆるやか。
.caption2 は変化が急。
ただ、よく見ると左上のX Smallは .largeTitle が小さくて、.caption2 が大きい。つまり

  • .largeTitle は小さくなりやすく、大きくなりにくい
  • .caption2 は小さくなりにくく、大きくなりやすい

イメージ図を載せる。
まずこれは.caption2 .body .largeTitle というフォントをxsmallからAX5まで変化させたときのイメージ図。

次は .font(.custom(_,size:,relativeTo:)) で数値と変化の仕方を与えたときのイメージ図

.largeTitleを選んだとき、ふつう以外の値は青のカーブを使って決まる。
.caption2を選んだとき、ふつう以外の値は赤のカーブを使って決まる。

.titleみたいに書きたい

extension Font {
    static let myFont = Font.custom("", size: 40)
}

とすると

Text("Hello, world!")
    .font(.myFont)

と書ける。Dynamic Typeにも対応済み。

変化の仕方で我々が求めているものは auto ではなかろうか

変化の仕方を指定するといっても、自動でうまいことやってくれてもいいのではないか(or 可能ではないか)という気もする。例えば次のようなものが考えられる。

  • 小さい値で指定したものは左方向へはあまり変わらず、右方向へはかなり大きくなる
  • 大きい値で指定したものは左方向へかなり小さくなる、右方向へは少し大きくなる
  • もっと大きい値で指定したものは左方向へもっとかなり小さくなる、右方向へは変わらない
  • Dynamic Typeの設定(図では横軸)がどこでも、値の大小関係は逆転することはない

Discussion