SwiftUI 视图
Text/Button/List、HStack/VStack、Modifier。
40 分钟
SwiftUI 视图
SwiftUI 用 View 协议描述界面:基础控件、布局容器、Modifier 链式组合。对照 /roadmaps/swift-ui「视图与布局」节点,掌握 Text/Button/List 与 HStack/VStack 即可搭建大部分页面。
学习目标
- 使用 Text、Image、Button、TextField 等基础控件
- 用 HStack、VStack、ZStack 与 Spacer 布局
- 理解 Modifier 顺序与 List/ForEach
- 创建可复用子视图与自定义 Modifier
核心概念
基础控件与布局
import SwiftUI
struct LessonCardView: View {
let lesson: Lesson
var onToggle: () -> Void
var body: some View {
HStack(spacing: 12) {
VStack(alignment: .leading, spacing: 4) {
Text(lesson.title)
.font(.headline)
Text(lesson.completed ? "已完成" : "进行中")
.font(.caption)
.foregroundStyle(.secondary)
}
Spacer()
Button(action: onToggle) {
Image(systemName: lesson.completed ? "checkmark.circle.fill" : "circle")
.font(.title2)
.foregroundStyle(lesson.completed ? .green : .gray)
}
.buttonStyle(.plain)
}
.padding()
.background(.background)
.clipShape(RoundedRectangle(cornerRadius: 12))
.shadow(color: .black.opacity(0.08), radius: 4, y: 2)
}
}
struct LessonListView: View {
@State private var lessons: [Lesson] = [
Lesson(id: 1, title: "SwiftUI 视图", completed: true),
Lesson(id: 2, title: "状态管理", completed: false),
Lesson(id: 3, title: "导航", completed: false),
]
var body: some View {
ScrollView {
LazyVStack(spacing: 12) {
ForEach(lessons) { lesson in
LessonCardView(lesson: lesson) {
toggleLesson(lesson.id)
}
}
}
.padding()
}
.navigationTitle("课时列表")
}
private func toggleLesson(_ id: Int) {
guard let i = lessons.firstIndex(where: { $0.id == id }) else { return }
lessons[i].completed.toggle()
}
}
Modifier 顺序影响结果:先 .padding() 再 .background() 与反过来视觉效果不同。
List 与样式 Modifier
struct SettingsRow: View {
let icon: String
let title: String
var body: some View {
Label(title, systemImage: icon)
.font(.body)
}
}
struct SettingsView: View {
var body: some View {
List {
Section("学习") {
SettingsRow(icon: "book", title: "继续学习")
SettingsRow(icon: "star", title: "收藏")
}
Section("账户") {
SettingsRow(icon: "person", title: "个人资料")
}
}
.listStyle(.insetGrouped)
}
}
#Preview {
NavigationStack {
LessonListView()
}
}