Skip to content

SwiftUI Patterns Skill 是 Everything Claude Code 插件体系中专为现代 iOS/macOS 项目设计的 SwiftUI 架构实践合集。它聚焦于 @Observable 状态管理、类型安全导航(NavigationStack)、高性能视图组合与渲染优化,帮助开发者(尤其是借助 Claude Code 等 AI 编程助手)系统性提升 SwiftUI 代码质量、可维护性和性能,避免常见反模式。无论是初学者还是追求深度定制的团队,都能借助本 Skill 快速落地生产级 UI 架构。

Everything Claude Code SwiftUI Patterns Skill:@Observable、导航、视图组合与性能优化现代 iOS 最佳实践

SwiftUI Patterns Skill 是 Everything Claude Code 插件库中专为 Apple 平台(iOS/macOS)UI 架构打造的生产级 Skill。它系统总结了 SwiftUI 领域的最佳实践,涵盖状态管理(尤其是 Observation 框架的 @Observable)、视图组合、类型安全导航、性能优化等核心主题。无论你是通过 Claude Code、Codex、Cursor 等 AI 编程助手自动生成 SwiftUI 代码,还是手动开发大型项目,这套 Skill 都能帮助你:

  • 选用最合适的状态管理模式,避免“全局重渲染”或“状态丢失”
  • 构建可维护、高性能的视图层级
  • 实现类型安全、可编程导航流程
  • 避免常见反模式,提升代码健壮性和团队协作效率

本指南将分步骤讲解如何在实际项目中用好 SwiftUI Patterns Skill,并结合代码示例,帮助你快速上手和深度定制。


1. 适用场景与触发条件

SwiftUI Patterns Skill 适用于如下场景:

  • 新建或重构 SwiftUI 界面,涉及状态管理、导航、数据流设计
  • 优化大型列表、复杂布局的渲染性能
  • 需要依赖注入、环境变量、可测试性提升
  • 希望团队成员/AI 生成的 SwiftUI 代码风格统一、易于维护

Skill 会在你:

  • 编辑 SwiftUI 视图、ViewModel、Router 等相关文件时自动激活
  • 明确请求“SwiftUI 状态管理”、“NavigationStack 路由”、“性能优化”等相关问题时被调用
  • 结合 swift-actor-persistenceswift-protocol-di-testing 等 Skill 协同使用时,自动补充架构建议

2. 使用流程 Step by Step

Step 1:选择合适的状态管理模式

SwiftUI Patterns Skill 会根据你的数据流和视图结构,推荐最简洁且高效的状态管理方式:

属性包装器适用场景
@State视图本地、简单值类型(如表单、切换)
@Binding父视图向子视图传递双向引用
@Observable拥有多个属性的模型类,支持细粒度属性追踪
@Environment全局依赖注入(如认证、主题、配置)

示例:用 @Observable 构建 ViewModel,实现属性级别的高效刷新

swift
@Observable
final class ItemListViewModel {
    private(set) var items: [Item] = []
    private(set) var isLoading = false
    var searchText = ""

    private let repository: any ItemRepository

    init(repository: any ItemRepository = DefaultItemRepository()) {
        self.repository = repository
    }

    func load() async {
        isLoading = true
        defer { isLoading = false }
        items = (try? await repository.fetchAll()) ?? []
    }
}

Skill 会自动建议用 @Observable 替代老旧的 ObservableObject/@Published,让 SwiftUI 只重绘实际发生变化的属性对应视图,极大提升性能。

Step 2:视图消费 ViewModel 的标准写法

swift
struct ItemListView: View {
    @State private var viewModel: ItemListViewModel

    init(viewModel: ItemListViewModel = ItemListViewModel()) {
        _viewModel = State(initialValue: viewModel)
    }

    var body: some View {
        List(viewModel.items) { item in
            ItemRow(item: item)
        }
        .searchable(text: $viewModel.searchText)
        .overlay { if viewModel.isLoading { ProgressView() } }
        .task { await viewModel.load() }
    }
}

Skill 会自动规避“在子视图内 new ViewModel”这类反模式,推荐由父视图注入,确保状态一致性。

Step 3:用 @Environment 实现依赖注入

Skill 推荐用 @Environment 替换 @EnvironmentObject,提升类型安全与解耦:

swift
// 注入
ContentView()
    .environment(authManager)

// 消费
struct ProfileView: View {
    @Environment(AuthManager.self) private var auth

    var body: some View {
        Text(auth.currentUser?.name ?? "Guest")
    }
}

这样可实现全局依赖(如认证、配置、主题等)注入,方便测试与复用。

Step 4:高效的视图组合与性能优化

  • 拆分小型 Subview,降低无关重渲染

    swift
    struct OrderView: View {
        @State private var viewModel = OrderViewModel()
    
        var body: some View {
            VStack {
                OrderHeader(title: viewModel.title)
                OrderItemList(items: viewModel.items)
                OrderTotal(total: viewModel.total)
            }
        }
    }
  • 用 ViewModifier 抽离复用样式

    swift
    struct CardModifier: ViewModifier {
        func body(content: Content) -> some View {
            content
                .padding()
                .background(.regularMaterial)
                .clipShape(RoundedRectangle(cornerRadius: 12))
        }
    }
    
    extension View {
        func cardStyle() -> some View {
            modifier(CardModifier())
        }
    }
  • 大列表用 LazyVStack/LazyHStack,避免一次性渲染全部内容

    swift
    ScrollView {
        LazyVStack(spacing: 8) {
            ForEach(items) { item in
                ItemRow(item: item)
            }
        }
    }
  • ForEach 必须用稳定的唯一 id,避免 UI 错乱或性能问题

    swift
    ForEach(items, id: \.stableID) { item in
        ItemRow(item: item)
    }
  • 避免在 body 里写 IO/网络/重计算,统一用 .task{} 触发异步加载

Step 5:类型安全的 NavigationStack 路由

Skill 推荐用 NavigationStack + NavigationPath + 枚举类型,实现可编程、类型安全的导航:

swift
@Observable
final class Router {
    var path = NavigationPath()

    func navigate(to destination: Destination) {
        path.append(destination)
    }

    func popToRoot() {
        path = NavigationPath()
    }
}

enum Destination: Hashable {
    case detail(Item.ID)
    case settings
    case profile(User.ID)
}

struct RootView: View {
    @State private var router = Router()

    var body: some View {
        NavigationStack(path: $router.path) {
            HomeView()
                .navigationDestination(for: Destination.self) { dest in
                    switch dest {
                    case .detail(let id): ItemDetailView(itemID: id)
                    case .settings: SettingsView()
                    case .profile(let id): ProfileView(userID: id)
                    }
                }
        }
        .environment(router)
    }
}

Skill 会自动生成路由器、导航枚举、类型安全的跳转方法,避免硬编码字符串或易错的 Any 类型。

Step 6:预览与测试

  • 推荐用 #Preview 宏 + Mock 数据,极大提升开发效率

    swift
    #Preview("Empty state") {
        ItemListView(viewModel: ItemListViewModel(repository: EmptyMockRepository()))
    }
    
    #Preview("Loaded") {
        ItemListView(viewModel: ItemListViewModel(repository: PopulatedMockRepository()))
    }

3. Skill 输出示例

当你请求“生成一个带搜索和加载指示的 SwiftUI 列表页面”时,AI 结合本 Skill 输出如下结构:

swift
@Observable
final class ItemListViewModel { ... }

struct ItemListView: View { ... }

#Preview("Loaded") { ... }

并自动用 .task{} 加载、用 @Observable 管理状态、用 NavigationStack 实现跳转,避免常见反模式。


4. 常见配套 Agent 与 Skill 协作


FAQ

Q: SwiftUI Patterns Skill 与传统 ObservableObject 有什么区别?
A: Skill 推荐用 @Observable 替代 ObservableObject,可实现属性级别的刷新,避免整页重绘,性能和可维护性更优。

Q: 如何防止 SwiftUI 列表渲染卡顿?
A: Skill 会建议用 LazyVStack/LazyHStack 处理大列表,并确保 ForEach 使用唯一稳定 id,避免重复渲染和 UI 错乱。

Q: Skill 会自动帮我生成类型安全的导航代码吗?
A: 是的,Skill 输出的 NavigationStack 路由器和枚举都具备类型安全,避免硬编码和运行时错误。