iOSSwiftUI模式Skill ios-swiftui-patterns

iOS SwiftUI模式是苹果平台应用开发中的声明式UI框架,用于构建高效、可维护的用户界面。它包括状态管理、视图组合、异步处理等核心概念和最佳实践,适用于iOS、macOS等移动和桌面应用的UI开发。关键词:iOS, SwiftUI, 声明式UI, 状态管理, 视图组合, 移动开发, 最佳实践。

移动开发 0 次安装 0 次浏览 更新于 3/25/2026

name: ios-swiftui-patterns user-invocable: false description: 在构建SwiftUI视图、使用@State/@Binding/@ObservableObject管理状态,或在iOS应用中实现声明式UI模式时使用。 allowed-tools:

  • 读取
  • 写入
  • 编辑
  • Bash
  • Grep
  • Glob

iOS - SwiftUI 模式

为iOS、macOS、watchOS和tvOS应用开发的现代声明式UI。

关键概念

状态管理层次

SwiftUI 提供了不同状态需求的属性包装器层次:

  • @State: 局部视图状态,由视图拥有
  • @Binding: 与其他地方拥有的状态双向连接
  • @StateObject: 创建并拥有一个 ObservableObject
  • @ObservedObject: 引用其他地方拥有的 ObservableObject
  • @EnvironmentObject: 通过视图层次进行依赖注入
  • @Environment: 访问系统提供的值

观察者模式 (iOS 17+)

@Observable
class UserModel {
    var name: String = ""
    var email: String = ""
    var isLoggedIn: Bool = false
}

struct ContentView: View {
    @State private var user = UserModel()

    var body: some View {
        UserProfileView(user: user)
    }
}

传统 ObservableObject 模式

class UserViewModel: ObservableObject {
    @Published var name: String = ""
    @Published var isLoading: Bool = false

    func fetchUser() async {
        isLoading = true
        defer { isLoading = false }
        // 获取逻辑
    }
}

struct UserView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        // 视图实现
    }
}

最佳实践

视图组合

将复杂视图拆分为更小、专注的组件:

struct OrderSummaryView: View {
    let order: Order

    var body: some View {
        VStack(spacing: 16) {
            OrderHeaderView(order: order)
            OrderItemsListView(items: order.items)
            OrderTotalView(total: order.total)
        }
    }
}

偏好值类型

尽可能使用结构体作为模型,以利用 SwiftUI 的高效差异:

struct Product: Identifiable, Equatable {
    let id: UUID
    var name: String
    var price: Decimal
    var quantity: Int
}

使用 ViewModifiers 进行可重用样式

struct CardModifier: ViewModifier {
    func body(content: Content) -> some View {
        content
            .padding()
            .background(Color(.systemBackground))
            .cornerRadius(12)
            .shadow(radius: 4)
    }
}

extension View {
    func cardStyle() -> some View {
        modifier(CardModifier())
    }
}

异步工作的任务生命周期

struct UserDetailView: View {
    let userId: String
    @State private var user: User?

    var body: some View {
        Group {
            if let user {
                UserContent(user: user)
            } else {
                ProgressView()
            }
        }
        .task {
            user = await fetchUser(id: userId)
        }
    }
}

常见模式

使用 NavigationStack 导航 (iOS 16+)

struct ContentView: View {
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            ProductListView()
                .navigationDestination(for: Product.self) { product in
                    ProductDetailView(product: product)
                }
                .navigationDestination(for: Category.self) { category in
                    CategoryView(category: category)
                }
        }
    }
}

Sheet 和 Alert 呈现

struct ItemView: View {
    @State private var showingDetail = false
    @State private var showingDeleteAlert = false

    var body: some View {
        Button("查看详情") {
            showingDetail = true
        }
        .sheet(isPresented: $showingDetail) {
            DetailSheet()
        }
        .alert("删除项目?", isPresented: $showingDeleteAlert) {
            Button("删除", role: .destructive) { deleteItem() }
            Button("取消", role: .cancel) { }
        }
    }
}

使用 SwiftData 的列表 (iOS 17+)

@Model
class Task {
    var title: String
    var isCompleted: Bool
    var createdAt: Date

    init(title: String) {
        self.title = title
        self.isCompleted = false
        self.createdAt = Date()
    }
}

struct TaskListView: View {
    @Query(sort: \Task.createdAt, order: .reverse)
    private var tasks: [Task]
    @Environment(\.modelContext) private var modelContext

    var body: some View {
        List(tasks) { task in
            TaskRowView(task: task)
        }
    }
}

反模式

避免大型单一视图

坏:

struct BadView: View {
    var body: some View {
        VStack {
            // 200+ 行嵌套视图
        }
    }
}

好:提取为专注的子视图。

不要将 @ObservedObject 用于拥有的状态

坏:

struct BadView: View {
    @ObservedObject var viewModel = ViewModel() // 每次视图初始化时重新创建!
}

好:

struct GoodView: View {
    @StateObject private var viewModel = ViewModel()
}

避免在视图主体中使用副作用

坏:

var body: some View {
    let _ = print("视图渲染") // 副作用!
    Text("Hello")
}

好:使用 .task, .onAppear, 或 .onChange 处理副作用。

不要在视图中强制解包

坏:

Text(user!.name) // 崩溃风险

好:

if let user {
    Text(user.name)
}

相关技能

  • ios-swift-concurrency: 数据加载的 async/await 模式
  • ios-uikit-architecture: 桥接 UIKit 和 SwiftUI 时