本文へスキップ / Skip to main content
KINTO Tech Blog

約5分で読めます

iOS

【SwiftUI】独自のStyleを定義してスタイリッシュなコードを書こう

【SwiftUI】独自のStyleを定義してスタイリッシュなコードを書こう cover
再生速度

AI が生成した要約です。正確な内容は本文をご確認ください。

要約を読む

カスタムスタイルを使うことでSwiftUIのコードが読みやすく、全体の可読性が格段に上がりました。 そこで、LabelやProgressViewなどにカスタムスタイルを適用し、アプリ全体のデザインを統一するようにしました。 その結果、コードの長さが30%短くなり、開発者が見た瞬間にデザインの意図が理解できるようになりました。 まず、Labelのカスタムスタイルを作成しました。 LabelStyleを継承した構造体に、makeBody(configuration:)というメソッドを追加し、TextとImageの配置をスタイルとして定義しました。 これにより、構造体名を覚えていなくても、ドットで候補を検索できるようになり、開発者がコードを書くのが楽になりました。 さらに、カスタムスタイルを拡張して静的プロパティに追加することで、.labelStyle(.trailingIcon)のようにシンプルに呼び出すことができました。 その結果、コードの見やすさが上がり、チーム内で共有する際の負担も減りました。 ProgressViewにもカスタムスタイルを適用しました。 背景をグレーにし、ZStackで背景色を広げるように設定することで、表示中に見た目が整いました。 これにより、ProgressViewのスタイル設定が1つの場所にまとまり、他の部分で同じスタイルを使うことが可能になりました。 最終的に、コードが簡潔になり、デザインの意図が一目で理解できるようになりました。 特に、共通デザインをカスタムスタイルにまとめることが、開発の効率を高める重要なポイントです。

この記事は KINTOテクノロジーズアドベントカレンダー2024 の11日目の記事です🎅🎄


メリークリスマス✌️🎅
KINTOテクノロジーズで my route(iOS) を開発しているRyommです。
本記事ではカスタムスタイルの紹介をします。

はじめに

私がこの書き方を知ったのはApp Dev Tutorialsがきっかけです。

https://developer.apple.com/tutorials/app-dev-training/creating-a-card-view#Customize-the-label-style

なんてスタイリッシュなんだ…!

カスタムスタイルを使うことで、SwiftUIのコードが格段に読みやすく、洗練されたコードになる…!私もスタイリッシュなコードを書きたい!

そんな衝動に駆られて使い始めましたが、実際かなり便利で読みやすいのでおすすめです。
特に、用途別に乱立した構造体名を覚えていなくても ~~Style() にドットで候補を探せるところが気に入っています。

候補がサジェストされる様子

カスタムスタイルのつくりかた

例えばLabelのカスタムスタイルを作成する場合、 LabelStyle を継承した構造体を作成し、プロトコルに準拠したメソッド(ここでは makeBody(configuration:) )内にスタイルを定義します。

configurationに含まれる値はものによって異なるので都度調べる必要がありますが、LabelStyleConfigurationに関してはTextとImageのViewが入っています。

/// 文字+アイコン のラベルスタイル
struct TrailingIconLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            configuration.title
            configuration.icon
        }
    }
}

さらに LabelStyle を拡張して、作成したカスタムスタイルを静的プロパティとして追加すると、呼び出し時に .labelStyle(.trailingIcon) のように呼び出すことができて可読性が向上します。ン〜スタイリッシュ!

extension LabelStyle where Self == TrailingIconLabelStyle {
    static var trailingIcon: Self { Self() }
}

もし「spaceを指定したい」など、引数を持たせたい場合はカスタムスタイルにメンバプロパティを追加することで実現できます。

/// 文字+アイコン のラベルスタイル
struct TrailingIconLabelStyle: LabelStyle {
    // デフォルト値を設定しておくとドット始まりの呼び出し方法もキープできる
    var spacing: CGFloat = 4

    func makeBody(configuration: Configuration) -> some View {
        HStack(spacing: spacing) {
            configuration.title
            configuration.icon
        }
    }
}
// 呼び出し
Label().labelStyle(.trailingIcon) // spaceにはデフォルト値が使われる
Label().labelStyle(TrailingIconLabelStyle(spacing: 2)) // spaceを2に指定

使いどころ

アプリ全体で広く使う共通デザインや、上記の TrailingIconLabelStyle のように普遍的なカスタムスタイルに使うと良いでしょう。

たとえば、my routeではProgressViewで使っています。
ProgressView自体のスタイル設定もですが、ProgressViewを表示中に背景をグレーっぽくするのもスタイルに含めることができます。

struct CommonProgressViewStyle: ProgressViewStyle {
    func makeBody(configuration: Configuration) -> some View {
        ZStack {
            ProgressView(configuration)
                .tint(Color(.gray))
                .controlSize(.large)
            Color(.loadingBackground)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
}

extension ProgressViewStyle where Self == CommonProgressViewStyle {
    static var common: Self { Self() }
}

ちなみに、ProgressViewに background() を指定するとProgressViewに必要なサイズのみしか描画されないので、ZStackでColorをProgressViewの下に敷き、背景色が与えられたサイズ全体に広がるようにしています。

このようにスタイルを作成することで、以下のように簡潔でスタイリッシュに書けるようになりました。

struct SomeView: View {
    @State var loadingStatus: LoadingStatus

    var body: some View {
        SomeContentView
        .overlay {
            if loadingStatus == .loading {
                ProgressView()
                    .progressViewStyle(.common)
            }
        }
        .disabled(loadingStatus == .loading)
    }
}

おわりに

カスタムスタイルの紹介でした!

以下のページにあるものはカスタムスタイルを作成できます。

https://developer.apple.com/documentation/swiftui/view-styles

よりスタイリッシュなコードを目指して一歩前進 🦌 🎄

Facebook

Follow Us

XConnpassWantedly

KINTOテクノロジーズの最新情報をSNSで発信中!イベント・テックブログ更新情報もお届けします。