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