SwiftUI入门 #
一、SwiftUI概述 #
SwiftUI是苹果推出的声明式UI框架,用于构建iOS、macOS、watchOS、tvOS和visionOS应用。
1.1 SwiftUI特点 #
- 声明式语法
- 跨平台支持
- 实时预览
- 状态驱动
- 现代化设计
二、基本视图 #
2.1 Text视图 #
swift
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, SwiftUI!")
.font(.largeTitle)
.foregroundColor(.blue)
.padding()
}
}
2.2 Image视图 #
swift
struct ImageView: View {
var body: some View {
Image(systemName: "swift")
.font(.system(size: 100))
.foregroundColor(.orange)
}
}
2.3 Button视图 #
swift
struct ButtonView: View {
var body: some View {
Button(action: {
print("按钮点击")
}) {
Text("点击我")
.font(.headline)
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
}
三、布局容器 #
3.1 VStack #
swift
struct VStackView: View {
var body: some View {
VStack(spacing: 10) {
Text("第一行")
Text("第二行")
Text("第三行")
}
.padding()
}
}
3.2 HStack #
swift
struct HStackView: View {
var body: some View {
HStack(spacing: 20) {
Text("左边")
Spacer()
Text("右边")
}
.padding()
}
}
3.3 ZStack #
swift
struct ZStackView: View {
var body: some View {
ZStack {
Color.blue
.edgesIgnoringSafeArea(.all)
Text("前景文字")
.font(.largeTitle)
.foregroundColor(.white)
}
}
}
3.4 List #
swift
struct ListView: View {
let items = ["苹果", "香蕉", "橙子", "葡萄"]
var body: some View {
List(items, id: \.self) { item in
Text(item)
}
.navigationTitle("水果列表")
}
}
四、状态管理 #
4.1 @State #
swift
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack {
Text("计数: \(count)")
.font(.largeTitle)
Button("增加") {
count += 1
}
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
}
}
4.2 @Binding #
swift
struct ToggleView: View {
@Binding var isOn: Bool
var body: some View {
Toggle("开关", isOn: $isOn)
.padding()
}
}
struct ParentView: View {
@State private var isOn = false
var body: some View {
VStack {
Text(isOn ? "开启" : "关闭")
ToggleView(isOn: $isOn)
}
}
}
4.3 @ObservedObject #
swift
class ViewModel: ObservableObject {
@Published var count = 0
}
struct ObservedView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
VStack {
Text("计数: \(viewModel.count)")
Button("增加") {
viewModel.count += 1
}
}
}
}
4.4 @StateObject #
swift
struct StateObjectView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
VStack {
Text("计数: \(viewModel.count)")
Button("增加") {
viewModel.count += 1
}
}
}
}
4.5 @EnvironmentObject #
swift
class AppSettings: ObservableObject {
@Published var userName = "张三"
}
struct EnvironmentView: View {
@EnvironmentObject var settings: AppSettings
var body: some View {
Text("用户: \(settings.userName)")
}
}
struct RootView: View {
@StateObject var settings = AppSettings()
var body: some View {
EnvironmentView()
.environmentObject(settings)
}
}
五、导航 #
5.1 NavigationView #
swift
struct NavigationExample: View {
var body: some View {
NavigationView {
List {
NavigationLink("第一页") {
DetailView(title: "第一页")
}
NavigationLink("第二页") {
DetailView(title: "第二页")
}
}
.navigationTitle("主页")
}
}
}
struct DetailView: View {
let title: String
var body: some View {
Text(title)
.font(.largeTitle)
.navigationTitle(title)
}
}
5.2 sheet #
swift
struct SheetView: View {
@State private var showSheet = false
var body: some View {
Button("显示Sheet") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
Text("这是一个Sheet")
}
}
}
六、表单 #
6.1 Form #
swift
struct FormView: View {
@State private var name = ""
@State private var age = 18
@State private var isAgree = false
var body: some View {
Form {
Section(header: Text("个人信息")) {
TextField("姓名", text: $name)
Stepper("年龄: \(age)", value: $age, in: 1...100)
}
Section(header: Text("协议")) {
Toggle("同意条款", isOn: $isAgree)
}
Section {
Button("提交") {
print("提交")
}
.disabled(!isAgree)
}
}
.navigationTitle("表单")
}
}
七、动画 #
7.1 基本动画 #
swift
struct AnimationView: View {
@State private var isExpanded = false
var body: some View {
Circle()
.frame(width: isExpanded ? 200 : 100, height: isExpanded ? 200 : 100)
.foregroundColor(isExpanded ? .blue : .red)
.animation(.easeInOut(duration: 0.5), value: isExpanded)
.onTapGesture {
isExpanded.toggle()
}
}
}
7.2 withAnimation #
swift
struct WithAnimationView: View {
@State private var offset: CGFloat = 0
var body: some View {
VStack {
Circle()
.frame(width: 50, height: 50)
.offset(x: offset)
Button("移动") {
withAnimation(.spring()) {
offset = offset == 0 ? 100 : 0
}
}
}
}
}
八、实战示例 #
8.1 待办事项列表 #
swift
struct TodoItem: Identifiable {
let id = UUID()
var title: String
var isCompleted = false
}
class TodoViewModel: ObservableObject {
@Published var items: [TodoItem] = []
func addItem(_ title: String) {
items.append(TodoItem(title: title))
}
func toggleItem(_ item: TodoItem) {
if let index = items.firstIndex(where: { $0.id == item.id }) {
items[index].isCompleted.toggle()
}
}
func deleteItem(_ item: TodoItem) {
items.removeAll { $0.id == item.id }
}
}
struct TodoListView: View {
@StateObject var viewModel = TodoViewModel()
@State private var newItemTitle = ""
var body: some View {
NavigationView {
VStack {
HStack {
TextField("添加新任务", text: $newItemTitle)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button("添加") {
if !newItemTitle.isEmpty {
viewModel.addItem(newItemTitle)
newItemTitle = ""
}
}
}
.padding()
List {
ForEach(viewModel.items) { item in
HStack {
Image(systemName: item.isCompleted ? "checkmark.circle.fill" : "circle")
.onTapGesture {
viewModel.toggleItem(item)
}
Text(item.title)
.strikethrough(item.isCompleted)
}
}
.onDelete { indexSet in
viewModel.items.remove(atOffsets: indexSet)
}
}
}
.navigationTitle("待办事项")
}
}
}
九、总结 #
本章学习了SwiftUI基础:
- 基本视图:Text、Image、Button
- 布局容器:VStack、HStack、ZStack、List
- 状态管理:@State、@Binding、@ObservedObject
- 导航:NavigationView、sheet
最佳实践:
- 使用声明式语法
- 合理管理状态
- 使用MVVM架构
- 利用预览功能
下一章,我们将学习网络请求!
最后更新:2026-03-26