小学理科718254 views
MathPython494013 views
高校物理158886 views
高校日本史190117 views
中学社会667610 views
世界の国562102 views
高校化学2917196 views
中学理科1628254 views
LaTeX959099 views
雑学1473058 views

SwiftUI LabelStyle の作成

LabelStyle プロトコルを使うと、Label の見た目をカスタマイズできる。アイコンとテキストの配置、サイズ、装飾などを自由に定義可能だ。

LabelStyle の基本

LabelStyle プロトコルは makeBody(configuration:) メソッドを実装する。

struct VerticalLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        VStack(spacing: 4) {
            configuration.icon
            configuration.title
        }
    }
}

configuration.iconconfiguration.title で、Label に渡されたアイコンとテキストにアクセスできる。

Label("設定", systemImage: "gear")
    .labelStyle(VerticalLabelStyle())

標準の LabelStyle

SwiftUI には組み込みのスタイルがいくつか用意されている。

Label("ファイル", systemImage: "doc")
    .labelStyle(.automatic)      // プラットフォームに応じた標準

Label("ファイル", systemImage: "doc")
    .labelStyle(.iconOnly)       // アイコンのみ

Label("ファイル", systemImage: "doc")
    .labelStyle(.titleOnly)      // タイトルのみ

Label("ファイル", systemImage: "doc")
    .labelStyle(.titleAndIcon)   // 両方表示

カスタムスタイルの実装

アイコンに背景をつけた、アプリの設定画面風のスタイル。

struct SettingsLabelStyle: LabelStyle {
    var iconColor: Color = .blue
    
    func makeBody(configuration: Configuration) -> some View {
        HStack(spacing: 12) {
            configuration.icon
                .font(.body)
                .foregroundColor(.white)
                .frame(width: 28, height: 28)
                .background(iconColor)
                .cornerRadius(6)
            
            configuration.title
                .font(.body)
        }
    }
}

extension LabelStyle where Self == SettingsLabelStyle {
    static func settings(color: Color = .blue) -> SettingsLabelStyle {
        SettingsLabelStyle(iconColor: color)
    }
}
List {
    Label("一般", systemImage: "gear")
        .labelStyle(.settings(color: .gray))
    
    Label("通知", systemImage: "bell.badge")
        .labelStyle(.settings(color: .red))
    
    Label("プライバシー", systemImage: "hand.raised")
        .labelStyle(.settings(color: .blue))
}

バッジ付きラベル

struct BadgeLabelStyle: LabelStyle {
    var badgeCount: Int
    
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            configuration.icon
            configuration.title
            
            Spacer()
            
            if badgeCount > 0 {
                Text("\(badgeCount)")
                    .font(.caption2.bold())
                    .foregroundColor(.white)
                    .padding(.horizontal, 6)
                    .padding(.vertical, 2)
                    .background(Color.red)
                    .clipShape(Capsule())
            }
        }
    }
}

通知件数などを表示するバッジ付きのラベルを簡単に作れる。

アニメーション対応

struct AnimatedLabelStyle: LabelStyle {
    @State private var isAnimating = false
    
    func makeBody(configuration: Configuration) -> some View {
        HStack(spacing: 8) {
            configuration.icon
                .rotationEffect(.degrees(isAnimating ? 360 : 0))
                .animation(.linear(duration: 2).repeatForever(autoreverses: false), value: isAnimating)
                .onAppear { isAnimating = true }
            
            configuration.title
        }
    }
}

ローディング中を表すために、アイコンが回転し続けるスタイル。

環境に応じた適応

struct AdaptiveLabelStyle: LabelStyle {
    @Environment(\.sizeCategory) var sizeCategory
    
    func makeBody(configuration: Configuration) -> some View {
        if sizeCategory >= .accessibilityLarge {
            VStack(alignment: .leading, spacing: 4) {
                configuration.icon
                    .font(.title)
                configuration.title
            }
        } else {
            HStack(spacing: 8) {
                configuration.icon
                configuration.title
            }
        }
    }
}

Dynamic Type の設定に応じてレイアウトを切り替える。アクセシビリティに配慮した設計が可能だ。

使いどころ

設定画面

アイコンに色付き背景を持たせた iOS 標準風のスタイル。

ナビゲーション

アイコンとテキストを縦に並べたタブバー風のスタイル。

リスト項目

バッジやアクセサリを追加したカスタムスタイル。

LabelStyle は Menu や NavigationLink 内の Label にも適用される。一度定義すれば、アプリ全体で統一したラベルの見た目を実現できる。