SwiftUIの基本を身につけたい方はこちら

【Xcode/Swift】端末の文字のテキストサイズ変更の「Dynamic Type」の対応について

この記事では、iPhoneの設定のテキストサイズ変更の対応について解説していきたいと思います。

iPhoneのテキストサイズ変更とは?

iPhoneの設定を開いて、アクセシビリティ > 画面表示とテキストサイズ > さらに大きな文字でテキストサイズを変更できます。
(ちなみに、画面表示と明るさ > テキストサイズを変更でも変更できますが、こちらからだと「さらに大きな文字」がありません。)

7+5の12段階で調整することができます。以下の画像は通常(真ん中)と一番大きいサイズと、一番小さいサイズの画像です。結構変わります。

こんな感じでアプリ側ではなく、OS側で文字の大きさが変えられます。ですので、iOSエンジニアは、これを知っておかなければなりません。

ちなみに、このテキストサイズを変更できる機能のことをDynamic Typeダイナミックタイプと言います。iOS11から使えるようになった機能です。

確認方法

シミュレーターや実機iPhoneで設定アプリからサイズを変更して確認できますが、SwiftUIのプレビューだと、一瞬で簡単に全ての画面が確認できます。

プレビューで からDynamic Type Variantsを選択すればプレビューで全ての画面を一気に確認できます。

Dynamic Typeに対応する。

このように文字の大きさが設定アプリによって変えられるので、ボタンとかのレイアウトが崩れることがあります。

なので、このボタンだけは、大きくしないようにとか、この大きさまで許容するとかそういう対応をしなければなりません。

ではどうやって対応するのかというと、.dynamicTypeSize(DynamicTypeSize)というモディファイアをつかいます。

全て同じ大きさにする手っ取り早い対応

超手っ取り早い方法は、大元のViewに、.dynamicTypeSize(.large)をつけましょう。そうすると、iPhoneの設定で変えても、変わらなくなります。

@main
struct SampleProjectApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .dynamicTypeSize(.large)
        }
    }
}

ただ、このDynamic Typeは、視覚障害者のための機能なので、対応しないよりかは、絶対に対応した方が良いです。

ちゃんとした対応

大元につけるだけなら、3秒でできます。しかし、視覚障害者を考えられてないアプリになってしまいます。では、ちゃんと対応しましょう。

ちゃんと対応するというのはどういうことかというと、文字の大きさの上限または下限を決めます。.dynamicTypeSize(DynamicTypeSize)DynamicTypeSizeは12段階あります。.largeが通常の設定の大きさです。

通常の7段階
.dynamicTypeSize(.xSmall)
.dynamicTypeSize(.small)
.dynamicTypeSize(.medium)
.dynamicTypeSize(.large) ←通常の大きさ
.dynamicTypeSize(.xLarge)
.dynamicTypeSize(.xxLarge)
.dynamicTypeSize(.xxxLarge)
さらに大きな文字
.dynamicTypeSize(.accessibility1)
.dynamicTypeSize(.accessibility2)
.dynamicTypeSize(.accessibility3)
.dynamicTypeSize(.accessibility4)
.dynamicTypeSize(.accessibility5)

このTypeを指定して、この大きさまで許容するという対応をするのがちゃんとした対応になります。

例えば、絶対に文字が…で省略されたくないボタンがあるとしましょう。以下のシミュレータでは、最後の3つが…になってしまっています。ですので、最後の三つを除外すれば良いだけです。(画面の大きさは今回考慮してません。)

ボタンに対して、

.dynamicTypeSize(DynamicTypeSize.xSmall...DynamicTypeSize.accessibility2)

というモディファイアをつけます。

要は、.xSmall.accessibility2まで許容するということです。

Button {
} label: {
    Text("上限を決めてください。")
        .padding(10)
        .background(Color.yellow)
        .cornerRadius(10)
        .lineLimit(1)
}
.dynamicTypeSize(DynamicTypeSize.xSmall...DynamicTypeSize.accessibility2)

これを全ての画面、オブジェクトで確認して、一つ一つつけるというのがちゃんとし対応になります。

ちなみに、DynamicTypeSize.xSmallは一番最初なので、省略しても良いですね。

.dynamicTypeSize(...DynamicTypeSize.accessibility2)

あとは、そもそも上限や下限を決めずに、文字が大きい場合は二行するとかUIが不自然にならないようにしましょう。

評価