apple-hig-designer について
apple-hig-designerは、iOSのデザイナーや開発者向けのスキルです。Apple Human Interface Guidelinesに沿った画面の作成と確認を、ネイティブコンポーネントやアクセシビリティの観点から支援します。
主な機能
- 01SwiftUIとUIKitのコンポーネント生成
- 02Apple HIGへの準拠確認
- 03VoiceOverとDynamic Typeへの対応
- 04セマンティックカラーとダークモード
- 05タイポグラフィ、余白、安全領域の指針
活用シーン
- 01ネイティブなiOS画面の構築
- 02画面のアクセシビリティ対応確認
- 03ライト・ダーク表示の配色設計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jamesrochabrun/ skills --skill apple-hig-designerインストール後、Claude Code で/apple-hig-designerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/accessibility.mdcolors.mdcomponents.mdlayout_spacing.mdtypography.mdscripts/audit_accessibility.shgenerate_ios_component.shvalidate_design.sh詳細
Apple HIG デザイナー
AppleのHuman Interface Guidelines(HIG)に沿って、美しくネイティブなiOSアプリをデザインします。ネイティブコンポーネント、適切なタイポグラフィ、セマンティックカラー、Appleのデザイン原則を活用して、アクセシブルで直感的なインターフェイスを作成します。
このスキルでできること
Appleのガイドラインに沿った、ネイティブな使い心地のiOSアプリのデザインと構築を支援します。
- iOSコンポーネントを生成 - SwiftUIおよびUIKitのコンポーネントを作成します
- デザインを検証 - Apple HIGへの準拠を確認します
- アクセシビリティを確保 - VoiceOver、Dynamic Type、色のコントラストに対応します
- デザイン原則を適用 - 明瞭性、従属性、奥行きを取り入れます
- セマンティックカラーを使用 - ダークモードを自動的にサポートします
- タイポグラフィを実装 - San Franciscoフォントシステムを使用します
- スペーシングに準拠 - 8ptグリッドシステムとセーフエリアを使用します
Appleのデザイン原則
1. 明瞭性
コンテンツを明確に、焦点を絞って表示します。
どのサイズでも読みやすいテキスト、正確で明快なアイコン、控えめで適切な装飾を用い、機能性を重視してデザインします。
// ✅ Clear, focused content
Text("Welcome back, Sarah")
.font(.title)
.foregroundColor(.primary)
// ❌ Unclear, cluttered
Text("Welcome back, Sarah!!!")
.font(.title)
.foregroundColor(.red)
.background(.yellow)
.overlay(Image(systemName: "star.fill"))
2. 従属性
UIは、コンテンツの理解と操作を支援しますが、コンテンツと競合することはありません。
コンテンツを最優先し、軽やかなビジュアル表現を用いて、コンテンツに焦点を保ち、ゆとりを持たせます。
// ✅ Content-focused
VStack(alignment: .leading, spacing: 8) {
Text("Article Title")
.font(.headline)
Text("Article content goes here...")
.font(.body)
.foregroundColor(.secondary)
}
.padding()
// ❌ Distracting UI
VStack(spacing: 8) {
Text("Article Title")
.font(.headline)
.foregroundColor(.white)
.background(.blue)
.border(.red, width: 3)
}
3. 奥行き
視覚的なレイヤーと現実感のある動きによって、階層を伝え、関係性の理解を促します。
明確な視覚的レイヤーと現実感のある動きが活気を与え、理解を促します。タッチ操作と見つけやすさによって楽しさを高め、コンテキストを失わずに機能へアクセスできるようにします。
// ✅ Clear depth hierarchy
ZStack {
Color(.systemBackground)
VStack {
// Card with elevation
CardView()
.shadow(radius: 8)
}
}
// Using blur for depth
Text("Content")
.background(.ultraThinMaterial)
iOS UIコンポーネント
ナビゲーションパターン
1. ナビゲーションバー
ナビゲーションとアクションのためのトップバーです。
NavigationStack {
List {
Text("Item 1")
Text("Item 2")
}
.navigationTitle("Title")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Add") {
// Action
}
}
}
}
ガイドライン:
- 最上位の画面では大きなタイトルを使用します
- 詳細画面ではインラインタイトルを使用します
- アクションは現在のコンテキストに関連するものにします
- ツールバー項目は最大2~3個にします
2. タブバー
最上位の画面遷移に使う下部ナビゲーションです。
TabView {
HomeView()
.tabItem {
Label("Home", systemImage: "house")
}
SearchView()
.tabItem {
Label("Search", systemImage: "magnifyingglass")
}
ProfileView()
.tabItem {
Label("Profile", systemImage: "person")
}
}
ガイドライン:
- タブは最大3~5個にします
- アイコンにはSF Symbolsを使用します
- ラベルは簡潔にします(1語)
- タブを非表示にしたり、無効にしたりしないでください
- 同じ画面でタブバーとツールバーを併用しないでください
3. リスト
スクロール可能な項目の一覧です。
List {
Section("Today") {
ForEach(items) { item in
NavigationLink {
DetailView(item: item)
} label: {
HStack {
Image(systemName: item.icon)
.foregroundColor(.accentColor)
Text(item.title)
}
}
}
}
}
.listStyle(.insetGrouped)
リストのスタイル:
.plain- 端から端まで表示する行.insetGrouped- 角丸でインセットされたセクション(iOSのデフォルト).sidebar- ナビゲーションサイドバー用
4. シート(モーダル)
コンテンツをモーダル表示します。
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Show Details") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
DetailView()
.presentationDetents([.medium, .large])
}
}
}
シートの表示高さ:
.medium- 画面の半分.large- 全画面- カスタムの高さも指定できます
フォームコントロール
1. ボタン
主要なアクションを実行するコントロールです。
// Filled button (primary action)
Button("Continue") {
// Action
}
.buttonStyle(.borderedProminent)
// Bordered button (secondary action)
Button("Cancel") {
// Action
}
.buttonStyle(.bordered)
// Plain button (tertiary action)
Button("Learn More") {
// Action
}
.buttonStyle(.plain)
ボタンの階層:
- 目立つボタン - 主要なアクション(画面ごとに1つ)
- 枠線付き - 二次的なアクション
- プレーン - 三次的なアクションやリンク
ガイドライン:
- タップ可能な領域は最低44x44ポイントにします
- ボタンのラベルには動詞を使います
- 破壊的なアクションには確認を必要とします
2. TextField
テキスト入力コントロールです。
@State private var username = ""
@State private var password = ""
VStack(alignment: .leading, spacing: 16) {
// Standard text field
TextField("Username", text: $username)
.textFieldStyle(.roundedBorder)
.textContentType(.username)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
// Secure field
SecureField("Password", text: $password)
.textFieldStyle(.roundedBorder)
.textContentType(.password)
}
テキストコンテンツタイプ:
.username- ユーザー名フィールド.password- パスワードフィールド.emailAddress- メールアドレスフィールド.telephoneNumber- 電話番号.creditCardNumber- クレジットカード番号
3. Toggle
ブール値を切り替えるコントロール(スイッチ)です。
@State private var isEnabled = false
Toggle("Enable notifications", isOn: $isEnabled)
.toggleStyle(.switch)
ガイドライン:
- ラベルで切り替えの対象を説明します
- 切り替えの効果は即座に反映します
- 2択の場合にのみ使用します
4. Picker
選択用のコントロールです。
@State private var selectedSize = "Medium"
let sizes = ["Small", "Medium", "Large"]
// Menu style
Picker("Size", selection: $selectedSize) {
ForEach(sizes, id: \.self) { size in
Text(size).tag(size)
}
}
.pickerStyle(.menu)
// Segmented style (for 2-5 options)
Picker("Size", selection: $selectedSize) {
ForEach(sizes, id: \.self) { size in
Text(size).tag(size)
}
}
.pickerStyle(.segmented)
Pickerのスタイル:
.menu- ドロップダウンメニュー(デフォルト).segmented- セグメントコントロール(選択肢は2~5個).wheel- スクロールホイール.inline- インラインリスト(フォーム内)
カードとコンテナ
カードビュー
struct CardView: View {
var body: some View {
VStack(alignment: .leading, spacing: 12) {
Text("Title")
.font(.headline)
Text("Description goes here with some details about the content.")
.font(.subheadline)
.foregroundColor(.secondary)
.lineLimit(2)
Spacer()
Button("Action") {
// Action
}
.buttonStyle(.borderedProminent)
}
.padding()
.frame(width: 300, height: 200)
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4)
}
}
タイポグラフィ
San Franciscoフォントシステム
読みやすさを最適化するために設計されたAppleのシステムフォントです。
// Dynamic Type text styles
Text("Large Title").font(.largeTitle) // 34pt
Text("Title").font(.title) // 28pt
Text("Title 2").font(.title2) // 22pt
Text("Title 3").font(.title3) // 20pt
Text("Headline").font(.headline) // 17pt semibold
Text("Body").font(.body) // 17pt regular
Text("Callout").font(.callout) // 16pt
Text("Subheadline").font(.subheadline) // 15pt
Text("Footnote").font(.footnote) // 13pt
Text("Caption").font(.caption) // 12pt
Text("Caption 2").font(.caption2) // 11pt
Dynamic Typeでカスタムフォントを使用する
// Custom font that scales with Dynamic Type
Text("Custom Text")
.font(.custom("YourFont-Regular", size: 17, relativeTo: .body))
フォントのウェイト
Text("Light").fontWeight(.light)
Text("Regular").fontWeight(.regular)
Text("Medium").fontWeight(.medium)
Text("Semibold").fontWeight(.semibold)
Text("Bold").fontWeight(.bold)
Text("Heavy").fontWeight(.heavy)
タイポグラフィのガイドライン
推奨事項:
- ✅ 一貫性を保つため、システムフォント(San Francisco)を使用します
- ✅ アクセシビリティのため、Dynamic Type に対応します
- ✅ セマンティックなテキストスタイル(.headline、.body など)を使用します
- ✅ 本文の最小サイズは 17pt にします
- ✅ 行間はフォントサイズの 120~145%にします
禁止事項:
- ❌ フォントサイズを増やしすぎないでください(システムスタイルを使用します)
- ❌ テキストを 11pt 未満にしないでください
- ❌ 長いテキストにすべて大文字を使用しないでください
- ❌ Dynamic Type を無効にしないでください
色
セマンティックカラー
ライトモード/ダークモードに自動的に適応する色です。
// UI Element Colors
Color(.label) // Primary text
Color(.secondaryLabel) // Secondary text
Color(.tertiaryLabel) // Tertiary text
Color(.quaternaryLabel) // Watermark text
Color(.systemBackground) // Primary background
Color(.secondarySystemBackground) // Secondary background
Color(.tertiarySystemBackground) // Tertiary background
Color(.systemFill) // Fill colors
Color(.secondarySystemFill)
Color(.tertiarySystemFill)
Color(.quaternarySystemFill)
Color(.separator) // Separator lines
Color(.opaqueSeparator) // Non-transparent separator
システムカラー
// Standard system colors (adapt to dark mode)
Color(.systemRed)
Color(.systemOrange)
Color(.systemYellow)
Color(.systemGreen)
Color(.systemMint)
Color(.systemTeal)
Color(.systemCyan)
Color(.systemBlue)
Color(.systemIndigo)
Color(.systemPurple)
Color(.systemPink)
Color(.systemBrown)
Color(.systemGray)
ダークモード対応のカスタムカラー
// Define adaptive color
extension Color {
static let customBackground = Color("CustomBackground")
}
// In Assets.xcassets, create color set with:
// - Any Appearance: #FFFFFF
// - Dark Appearance: #000000
色のコントラストに関するガイドライン
WCAG AA 準拠:
- 通常のテキスト:コントラスト比は最低 4.5:1
- 大きなテキスト(24pt 以上):コントラスト比は最低 3:1
- UI コンポーネント:コントラスト比は 3:1
カスタムカラー:
- コントラストを上げる設定を有効にしてテストします
- 重要なテキストでは 7:1 を目指します
- どちらのモードでも十分なコントラストを確保します
間隔とレイアウト
8 ポイントグリッドシステム
すべての間隔を 8 の倍数にします。
// Spacing values
.padding(8) // 8pt
.padding(16) // 16pt (standard)
.padding(24) // 24pt
.padding(32) // 32pt
.padding(40) // 40pt
.padding(48) // 48pt
// Edge-specific padding
.padding(.horizontal, 16)
.padding(.vertical, 24)
.padding(.top, 16)
.padding(.bottom, 16)
セーフエリア
デバイスのセーフエリアを尊重します。
// Content within safe area (default)
VStack {
Text("Content")
}
// Extend beyond safe area
VStack {
Color.blue
}
.ignoresSafeArea()
// Extend top only
VStack {
Color.blue
}
.ignoresSafeArea(edges: .top)
タッチターゲット
インタラクティブ要素の最小サイズは 44x44 ポイントです。
Button("Tap") {
// Action
}
.frame(minWidth: 44, minHeight: 44)
間隔に関するガイドライン
// Component spacing
VStack(spacing: 8) { // Tight spacing
Text("Line 1")
Text("Line 2")
}
VStack(spacing: 16) { // Standard spacing
Text("Section 1")
Text("Section 2")
}
VStack(spacing: 24) { // Loose spacing
SectionView()
SectionView()
}
アクセシビリティ
VoiceOver のサポート
視覚障害のあるユーザーや弱視のユーザー向けのスクリーンリーダーです。
// Accessible label
Image(systemName: "heart.fill")
.accessibilityLabel("Favorite")
// Accessible value
Slider(value: $volume)
.accessibilityLabel("Volume")
.accessibilityValue("\(Int(volume * 100))%")
// Accessible hint
Button("Share") {
share()
}
.accessibilityHint("Shares this item with others")
// Group elements
HStack {
Image(systemName: "person")
Text("John Doe")
}
.accessibilityElement(children: .combine)
// Hidden from VoiceOver
Image("decorative")
.accessibilityHidden(true)
Dynamic Type
ユーザーが希望するテキストサイズに対応します。
// Automatically supported with system fonts
Text("This text scales")
.font(.body)
// Limit scaling (if necessary)
Text("This text has limits")
.font(.body)
.dynamicTypeSize(...DynamicTypeSize.xxxLarge)
// Custom font with Dynamic Type
Text("Custom font")
.font(.custom("YourFont", size: 17, relativeTo: .body))
色覚特性
色覚特性のあるユーザーに配慮して設計します。
// Don't rely on color alone
HStack {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
Text("Success")
}
// Not just color
Circle()
.fill(.green)
// ❌ Color only
// Better with shape/icon
HStack {
Image(systemName: "checkmark.circle.fill")
Circle().fill(.green)
}
// ✅ Color + shape
モーションを減らす
ユーザーのモーションに関する設定を尊重します。
@Environment(\.accessibilityReduceMotion) var reduceMotion
var animation: Animation {
reduceMotion ? .none : .spring()
}
Button("Animate") {
withAnimation(animation) {
// Animate
}
}
コントラストを上げる
ハイコントラストモードに対応します。
@Environment(\.colorSchemeContrast) var contrast
var textColor: Color {
contrast == .increased ? .primary : .secondary
}
Text("Content")
.foregroundColor(textColor)
ダークモード
ライトモードとダークモードの両方に対応します。
自動対応
// Use semantic colors (automatic)
Color(.label) // Adapts automatically
Color(.systemBackground) // Adapts automatically
ダークモードのテスト
// Preview both modes
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.light)
ContentView()
.preferredColorScheme(.dark)
}
}
ダークモードのガイドライン
推奨事項:
- ✅ セマンティックカラーを使用します
- ✅ コントラストを上げる設定を有効にしてテストします
- ✅ 透明度を下げる設定を有効にしてテストします
- ✅ どちらのモードでも十分なコントラストを確保します
禁止事項:
- ❌ 純粋な黒(#000000)を使用しないでください。systemBackground を使用します
- ❌ 色を自動的に反転しないでください
- ❌ ユーザーの設定を決めつけないでください
SF Symbols
Apple のアイコンシステム(3000 以上のシンボル)です。
// Basic symbol
Image(systemName: "heart")
// Colored symbol
Image(systemName: "heart.fill")
.foregroundColor(.red)
// Sized symbol
Image(systemName: "heart")
.imageScale(.large)
// Font-based sizing
Image(systemName: "heart")
.font(.title)
// Multicolor symbols
Image(systemName: "person.crop.circle.fill.badge.checkmark")
.symbolRenderingMode(.multicolor)
// Hierarchical rendering
Image(systemName: "heart.fill")
.symbolRenderingMode(.hierarchical)
.foregroundColor(.red)
SF Symbols のガイドライン
- 利用できる場合はシステムシンボルを使用します
- 視覚的なウェイトの一貫性を保ちます
- セマンティックな意味を表す場合はマルチカラーを使用します
- 用途に合ったサイズにします
アプリアイコン
アイコンのサイズ
iOS:
- 1024x1024 (App Store)
- 180x180 (iPhone @3x)
- 120x120 (iPhone @2x)
- 167x167 (iPad Pro)
- 152x152 (iPad @2x)
watchOS:
- 1024x1024 (App Store)
- 196x196 (49mm)
- 216x216 (45mm)
アイコンデザインのガイドライン
推奨事項:
- ✅ シンプルで認識しやすい形状を使用します
- ✅ アイコンの領域全体を使います
- ✅ モックアップだけでなく、デバイス上でもテストします
- ✅ 一貫したビジュアルスタイルを使用します
禁止事項:
- ❌ テキストを含めないでください(非常に小さく表示されます)
- ❌ 写真を使用しないでください
- ❌ Apple のハードウェアを模倣しないでください
- ❌ 半透明を使用しないでください
アニメーションとモーション
標準アニメーション
// Spring animation (natural, bouncy)
withAnimation(.spring()) {
offset = 100
}
// Linear animation
withAnimation(.linear(duration: 0.3)) {
opacity = 0
}
// Ease in/out
withAnimation(.easeInOut(duration: 0.3)) {
scale = 1.2
}
ジェスチャー駆動
@State private var offset = CGSize.zero
var body: some View {
Circle()
.offset(offset)
.gesture(
DragGesture()
.onChanged { value in
offset = value.translation
}
.onEnded { _ in
withAnimation(.spring()) {
offset = .zero
}
}
)
}
モーションに関するガイドライン
- アニメーションは 0.3 秒未満にします
- インタラクティブな要素にはスプリングアニメーションを使用します
- 「モーションを減らす」設定を尊重します
- すべての操作に視覚的なフィードバックを提供します
ベストプラクティス
ナビゲーション
- 階層型 - 詳細画面への移動には NavigationStack を使用します
- フラット型 - 同列の画面への移動には TabView を使用します
- コンテンツ主導型 - メディアアプリで使用します
フィードバック
- 視覚 - タップ時にハイライトします
- 触覚 - UIImpactFeedbackGenerator を使用します
- 音声 - システムサウンドは控えめに使用します
読み込み状態
struct LoadingView: View {
var body: some View {
VStack {
ProgressView()
.scaleEffect(1.5)
Text("Loading...")
.font(.caption)
.foregroundColor(.secondary)
.padding(.top)
}
}
}
エラー状態
struct ErrorView: View {
let message: String
let retry: () -> Void
var body: some View {
VStack(spacing: 16) {
Image(systemName: "exclamationmark.triangle")
.font(.system(size: 48))
.foregroundColor(.orange)
Text("Something went wrong")
.font(.headline)
Text(message)
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
Button("Try Again") {
retry()
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}
空の状態
struct EmptyStateView: View {
var body: some View {
VStack(spacing: 16) {
Image(systemName: "tray")
.font(.system(size: 64))
.foregroundColor(.secondary)
Text("No Items")
.font(.title2)
Text("Your items will appear here")
.font(.subheadline)
.foregroundColor(.secondary)
Button("Add Item") {
// Action
}
.buttonStyle(.borderedProminent)
}
}
}
プラットフォームに関する考慮事項
iPhone
- さまざまなサイズ(SE、Pro、Pro Max)に対応するデザインにします
- 縦向きと横向きに対応します
- ノッチ/Dynamic Island にはセーフエリアを使用します
- 片手での操作を考慮します
iPad
- マルチタスク(Split View、Slide Over)に対応します
- ナビゲーションにはサイドバーを使用します
- 大きな画面に合わせて調整します(単に拡大するだけにしません)
- キーボードショートカットを考慮します
- 外部ディスプレイに対応します
Apple Watch
- ひと目で把握できる情報を表示します
- 大きなタッチターゲット(>44pt)にします
- 必要な操作を最小限にします
- スクロールには Digital Crown を使用します
- 常時表示ディスプレイに対応します
リソース
「デザインとは、見た目や使い心地だけではありません。デザインとは、どのように機能するかです。」 - Steve Jobs