SwiftUIのSectionは、FormやList内の要素を論理的にグループ化するためのコンテナコンポーネントです。システムのスペーシング、角丸、オプションのヘッダーとフッターを備えた視覚的なブロックとしてコンテンツを表示します。Apple Developer Documentation (2025)によると、Sectionはデータを管理せず、プレゼンテーションのみを整理します。すべての子要素はそのスタイルとスペーシングを継承し、フォームとリストの構造化された表示を提供します。
重要ポイント
Sectionは、FormやListコンテナ内で要素をグループ化するために設計されたSwiftUIの構造的コンポーネントです。VStackやHStackとは異なり、Sectionはシステムのスペーシング、ヘッダーとフッター、そしてiOSでは角丸ブロックによる視覚的なグループ強調表示を追加します。
Sectionは子要素の動作を変更しません。プレゼンテーションのみを整理します。Section内のすべてのコントロール(Picker、Toggle、TextField)は通常通り動作しますが、視覚的に論理グループに結合されます。これは、ユーザーがデータ入力構造をすばやく把握する必要がある画面上のフォームで特に重要です。
システムはセクション間のスペーシングを自動的に管理します。iOSでのSection間の距離は16~20ポイント、Section内の要素間は0(行間の区切り)です。開発者はパディング修飾子を使ってこれらのスペーシングを変更できません。一貫した外観を確保するためにシステムによって制御されています。
Sectionは2つのオプションパラメータを受け入れます。headerはグループのタイトル、footerはグループの下に説明テキストを表示します。ヘッダーはセクション要素の上に太字のキャプションスタイルフォントで表示され、フッターは灰色の小さなフォントで表示されます。両方のパラメータはTextだけでなく、任意のSwiftUI Viewを受け入れます。
Sectionのヘッダーは、グループ内の要素がどのカテゴリに属するかをユーザーが理解するのに役立ちます。例えば、設定画面では「通知」「プライバシー」「アカウント」などのヘッダーがユーザーを即座に導きます。フッターは説明に便利です。「会議中は通知をオフにする」や「パスワードは8文字以上必要です」など。フッターは必要に応じて自動的に複数行に折り返されます。
Section(
header: Text("Account Security"),
footer: Text("Use a strong password with at least 8 characters.")
) {
SecureField("Current password", text: $currentPassword)
SecureField("New password", text: $newPassword)
}
この例では、Sectionに「Account Security」というヘッダーとパスワードセキュリティのアドバイスを含むフッターがあります。ユーザーはヘッダーをセクションラベルとして見て、2つのフィールドに入力し、その下の警告をすぐに読むことができます。この構造により、セクションに関するすべての情報が1つの画面に表示され、別のヘルプページに移動する必要がないため、UXが向上します。
SectionはFormとListの両方で機能しますが、視覚的な表現は異なります。Formでは、Sectionは角丸とシステム背景を持つブロックとして表示され、スペーシングによって隣接するセクションと区切られます。Listでは、Sectionはplainスタイル(背景と角丸なし)またはinset-grouped(Formと同様の角丸ブロック)を使用できます。
コンテナの選択はSectionのスタイルに影響します。同じコンテンツのSectionをFormとList(.insetGroupedスタイル)に配置すると、結果は同じになります。ただし、Formはデフォルトでシステムスペーシングを追加しgroupedスタイルを使用しますが、Listは.listStyle(.insetGrouped)修飾子で明示的にスタイルを指定する必要があります。
| コンテナ | デフォルトのSection | 利用可能なスタイル |
|---|---|---|
| Form | 角丸のInsetGrouped | .grouped(Formのみ) |
| List | Plain — セクション背景なし | .plain, .inset, .insetGrouped, .sidebar |
Listで同じ外観を実現するには、.listStyle(.insetGrouped)を使用します。このスタイルはFormの外観を模倣し、List上に構築された設定画面に適しています。標準のデータリストでは、.plainを使用します。セクションの強調表示はなく、行間に細い区切り線があります。
SectionはForEachを通じて動的な数の要素を含めることができます。これにより、グループ全体のヘッダーとフッターを維持しながら、繰り返し要素を持つグループを作成できます。Section内のForEachはデータコレクションを反復処理し、セクション構造を壊すことなく各要素の子Viewを作成します。
動的セクションは、オプションの数が可変の設定画面で役立ちます。利用可能な言語のリスト、接続デバイス、プッシュ購読など。セクションのヘッダーは静的で、コンテンツはデータに応じて変化します。
struct DynamicSectionView: View {
let categories = ["Work", "Personal", "Finance", "Health"]
@State private var selected = Set<String>()
var body: some View {
Form {
Section(header: Text("Categories"),
footer: Text("Select your preferred categories")) {
ForEach(categories, id: \.self) { category in
Toggle(category, isOn: Binding(
get: { selected.contains(category) },
set: { if $0 { selected.insert(category) }
else { selected.remove(category) } }
))
}
}
Section {
Text("Selected: \(selected.count) categories")
.foregroundStyle(.secondary)
}
}
}
}
この例では、ForEachがcategories配列の各カテゴリに対してToggleを生成します。セクションのヘッダーとフッターは1回設定され、グループ全体に適用されます。2番目のセクションは選択されたカテゴリの数を表示します。これはForEachに依存せず静的です。このアプローチにより、ヘッダーとフッターが動的要素のグループを文脈付ける柔軟なフォームを作成できます。
データグループ化にSectionを使用した完全なプロフィール画面の例を見てみましょう。フォームには3つのセクションがあります。ユーザー情報、プライバシー設定、統計情報です。各セクションは独自のヘッダーを使用し、最後のセクションには概要情報のフッターがあります。
struct ProfileView: View {
@State private var displayName = "Alex Johnson"
@State private var bio = "iOS developer"
@State private var isProfilePublic = true
@State private var showEmail = false
var body: some View {
Form {
Section(header: Text("Profile Info")) {
TextField("Display name", text: $displayName)
TextField("Bio", text: $bio, axis: .vertical)
.lineLimit(3)
}
Section(header: Text("Privacy")) {
Toggle("Public profile", isOn: $isProfilePublic)
Toggle("Show email", isOn: $showEmail)
.disabled(!isProfilePublic)
}
Section(header: Text("Stats"),
footer: Text("Last updated today at 2:30 PM")) {
LabeledContent("Posts", value: "42")
LabeledContent("Followers", value: "1,280")
LabeledContent("Following", value: "346")
}
}
.navigationTitle("Profile")
}
}
3つのSectionが機能領域を明確に分離します。編集可能なプロフィールフィールド、プライバシートグル、統計情報です。2番目のセクションは検証を示しています。「Show email」トグルはプロフィールが公開されるまで無効です。3番目のセクションのフッターは最終更新時刻を表示します。これは追加のコンテキスト情報にフッターを使用する例です。LabeledContentはFormでキーと値のペアを表示する標準のSwiftUIコンポーネントです。
Section(
header: HStack {
Image(systemName: "bell.fill")
.foregroundStyle(.blue)
Text("Notifications")
.font(.headline)
},
footer: Text("Manage push and email alerts")
) {
Toggle("Push notifications", isOn: $push)
Toggle("Email notifications", isOn: $email)
Stepper("Quiet hours: \(quietStart) — \(quietEnd)",
value: $quietStart,
in: 0...23)
}
この例は、headerが任意のSwiftUI Viewであることを示しています。ImageとTextでHStackを使用すると、ヘッダーの横にアイコンが追加され、セクションが視覚的に表現力豊かになります。カスタムヘッダーは、通知設定、有料機能、警告付きセクションなど、インターフェースの重要なセクションを強調するのに役立ちます。ただし、カスタムヘッダーの使いすぎは推奨されません。インターフェースの一貫性を保つには、画面ごとに1〜2の非標準スタイルのセクションで十分です。
よくある質問
いいえ、SectionはSwiftUIでネストをサポートしていません。Sectionを別のSectionの中に入れようとするとコンパイルエラーになります。階層的なグループ化には、Section内でListをOutlineGroupまたはDisclosureGroupと共に使用してください。
Section間のスペーシングはシステムによって管理され、パディング修飾子では変更できません。iOSではセクション間の距離は16〜20ポイントで、HIGに従っています。スペーシングに影響を与える唯一の方法はカスタムListStyleを使用することですが、これは推奨されません。
Groupは視覚的なスタイリングなしで要素をグループ化するための不可視のコンテナです。Sectionはヘッダー、フッター、スペーシング、および視覚的なブロックを追加します。Groupは条件付きレンダリングに使用され、Sectionはインターフェースの構造化に使用されます。
はい、Sectionは自動的にアクセシビリティラベルを追加します。セクションヘッダーはグループのアクセシビリティヘッダーに、フッターはアクセシビリティヒントになります。VoiceOverはセクションに入る前にヘッダーを読み上げ、障害を持つユーザーのナビゲーションを向上させます。
いいえ、SectionはFormまたはListの中でのみ機能します。これらのコンテナの外でSectionを使用するとコンパイルエラーになります。VStackやScrollViewで要素をグループ化するには、Groupまたは手動でスペーシングを設定したカスタムViewを使用してください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。