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.icon と configuration.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 にも適用される。一度定義すれば、アプリ全体で統一したラベルの見た目を実現できる。











