カスタム行のデザイン
List のデフォルト表示では物足りない場合、カスタム行を作成して独自のデザインを実現できます。再利用可能なコンポーネントとして切り出す方法も含めて解説します。
基本的なカスタム行
List の各行には任意の SwiftUI ビューを配置できます。HStack を使って横並びのレイアウトを作るのが基本パターンです。
struct ContentView: View {
var body: some View {
List {
HStack {
Image(systemName: "person.circle.fill")
.font(.title)
.foregroundColor(.blue)
VStack(alignment: .leading) {
Text("山田太郎")
.font(.headline)
Text("yamada@example.com")
.font(.subheadline)
.foregroundColor(.gray)
}
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.gray)
}
}
}
}再利用可能な行コンポーネント
同じデザインの行を複数箇所で使う場合は、別のビューとして切り出します。
struct UserRow: View {
let user: User
var body: some View {
HStack {
Image(systemName: "person.circle.fill")
.font(.title)
.foregroundColor(.blue)
VStack(alignment: .leading) {
Text(user.name)
.font(.headline)
Text(user.email)
.font(.subheadline)
.foregroundColor(.gray)
}
}
}
}
struct User: Identifiable {
let id = UUID()
var name: String
var email: String
}
struct ContentView: View {
let users = [
User(name: "山田太郎", email: "yamada@example.com"),
User(name: "佐藤花子", email: "sato@example.com")
]
var body: some View {
List(users) { user in
UserRow(user: user)
}
}
}複雑なレイアウトの行
画像、タイトル、サブタイトル、バッジなどを含む複雑な行も自由に作成できます。
struct ProductRow: View {
let product: Product
var body: some View {
HStack(spacing: 12) {
// 商品画像
RoundedRectangle(cornerRadius: 8)
.fill(Color.gray.opacity(0.3))
.frame(width: 60, height: 60)
.overlay {
Image(systemName: "photo")
.foregroundColor(.gray)
}
// 商品情報
VStack(alignment: .leading, spacing: 4) {
Text(product.name)
.font(.headline)
Text(product.category)
.font(.caption)
.foregroundColor(.secondary)
HStack {
Text("¥\(product.price)")
.font(.subheadline)
.fontWeight(.bold)
.foregroundColor(.blue)
if product.isOnSale {
Text("SALE")
.font(.caption2)
.fontWeight(.bold)
.foregroundColor(.white)
.padding(.horizontal, 6)
.padding(.vertical, 2)
.background(Color.red)
.cornerRadius(4)
}
}
}
Spacer()
}
.padding(.vertical, 4)
}
}行のパディング調整
List は自動的に行にパディングを追加します。これを調整したい場合は listRowInsets モディファイアを使います。
List {
HStack {
Color.blue
Text("端から端まで")
}
.listRowInsets(EdgeInsets()) // パディングをゼロに
}listRowInsets
行の内側の余白を調整する。EdgeInsets() を渡すとパディングがゼロになる。
listRowBackground
行の背景色やビューをカスタマイズする。
listRowSeparator
区切り線の表示・非表示を制御する。
条件付きスタイリング
データの状態に応じて行の見た目を変えることもできます。
struct TaskRow: View {
let task: Task
var body: some View {
HStack {
Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle")
.foregroundColor(task.isCompleted ? .green : .gray)
Text(task.title)
.strikethrough(task.isCompleted)
.foregroundColor(task.isCompleted ? .gray : .primary)
}
}
}カスタム行を作成する際は、再利用性を意識してビューを分割し、データモデルと表示ロジックを明確に分離することがポイントです。











