【Swift】文字サイズを端末サイズに応じて動的に変えたい

本投稿は TECOTEC Advent Calendar 2024 の4日目の記事です。

証券フロンティア事業部の神山です。普段はエンジニアとしてiOSアプリの開発を行なっています。

今回は、アプリのリファクタリングをしている中で、端末によってデザインが異なる箇所をできるだけ統一するようにした方法についてご紹介したいと思います。

経緯・やりたかったこと

アプリのデザインを作成する際に端末幅が375ポイント(iPhone XSやiPhone12 mini)を基準としているのですが、iPhone15 Pro Maxなどの大きい端末で確認してみると、想定されたデザインよりフォントサイズなどが全体的に小さい感じがしました。それもそのはずで、たとえばiPhone15 Pro Maxでは端末幅が430ポイントあるので、375ポイントを基準とした場合には約1.15倍(430 / 375)のサイズ差があります。

そのため、同じフォントサイズで作成した場合は大きい端末になればなるほど相対的に小さく見えます。画像は上から53、20、10ポイントのフォントサイズを指定してみました。

iPhone SE 3rd generation(375ポイント) iPhone15 Pro Max(430ポイント)

やりたいこととしては、iPhone15 Pro MaxでもiPhone SE 3rd generationで表示されている幅間で表示することなので、端末が異なっても全て同じように表示できるように調整していきます。

実装

まずは端末幅を取得できるようにします。※ 今回はマルチウィンドウは考慮しないこととします

extension UIWindow {
    static let connectedScene = UIApplication.shared.connectedScenes
        .compactMap { $0 as? UIWindowScene }
        .first
}

enum Device {
     static let width: CGFloat = UIWindow.connectedScene?.screen.bounds.width ?? .zero
}

そして、基準となるポイントを定義して端末幅に対してどれぐらいの差があるのかを倍率として取得できるようにしておきます。

enum Device {
    static var widthRatio: CGFloat {
        width / baseWidth
    }

    static let baseWidth: CGFloat = 375.0
    static let width: CGFloat = UIWindow.connectedScene?.screen.bounds.width ?? baseWidth
}

あとはフォントサイズを設定する際に、この倍率を適用するだけです。複数箇所で使用するのでextensionで定義しておくと便利かもしれません。

extension CGFloat {
    static func applyWidthRatio(baseSize: CGFloat) -> CGFloat {
        baseSize * Device.widthRatio
    }
}

先ほどのにapplyWidthRatio(baseSize:)を適用すると以下の画像のようになりました。iPhone 15 Pro MaxでもiPhone SE 3rd generationと同じように表示されていることが分かります。

iPhone SE 3rd generation(375ポイント) iPhone15 Pro Max(430ポイント)

まとめ

アプリで表示するサイズについてはDynamic Typeの適用などもあるため、様々なことを考慮する必要があり複雑になりがちですが、より良いアプリ作りのためにはとても重要な部分になるかと思います。この記事が少しでも参考になれば幸いです。

最後まで記事を読んで頂き、ありがとうございました。

テコテックの採用活動について

テコテックでは新卒採用、中途採用共に積極的に募集をしています。
採用サイトにて会社の雰囲気や福利厚生、募集内容をご確認いただけます。
ご興味を持っていただけましたら是非ご覧ください。 tecotec.co.jp