Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第5章:视图集成与数据流

第5章:视图集成与数据流

如何在 SwiftUI 视图中使用 @Query

1. @Query 宏的基本用法

@Query 是 SwiftData 与 SwiftUI 深度集成的核心特性,允许以声明式方式在视图中直接绑定数据查询:

import SwiftData
import SwiftUI

struct BookListView: View {
    @Query(sort: \Book.title) private var books: [Book]
    
    var body: some View {
        List(books) { book in
            Text(book.title)
        }
    }
}

关键特性:

  • 自动数据绑定:当底层数据变化时视图自动更新
  • 零样板代码:无需手动处理ModelContext或FetchRequest
  • 编译时安全:属性路径通过KeyPath验证

2. 配置查询参数

@Query支持完整的查询配置能力:

// 完整参数配置示例
@Query(
    filter: #Predicate<Book> { $0.rating > 3 },
    sort: [SortDescriptor(\Book.publishDate, order: .reverse)],
    animation: .default
) var topRatedBooks: [Book]

可配置项:

参数类型说明
filter#Predicate使用Swift原生谓词语法
sortSortDescriptor单字段或多字段排序
animationAnimation?数据变化时的过渡动画

3. 动态查询更新

通过参数绑定实现动态查询:

struct CategoryView: View {
    let selectedCategory: String
    
    var body: some View {
        // 当selectedCategory变化时自动重新查询
        BookList(category: selectedCategory)
    }
}

struct BookList: View {
    let category: String
    @Query var books: [Book]
    
    init(category: String) {
        _books = Query(
            filter: #Predicate { $0.category == category },
            sort: \Book.title
        )
    }
}

4. 与@Environment的协同工作

最佳实践是将@Query与SwiftUI环境值结合使用:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .modelContainer(for: Book.self)
        }
    }
}

struct ContentView: View {
    @Environment(\.modelContext) private var context
    @Query var books: [Book]
    
    func deleteBook(_ book: Book) {
        context.delete(book)
    }
}

5. 性能优化提示

  1. 分页加载:
@Query(sort: \Book.title, limit: 50) var firstPage: [Book]
  1. 避免过度更新:
// 对于不频繁变化的数据
@Query(animation: nil) var staticData: [Author] 
  1. 派生属性处理:
@Query var books: [Book]
var count: Int { books.count } // 避免在body中直接计算

var body: some View {
    Text("Total: \(count)")
}

常见问题解决方案

Q:为什么我的视图没有自动更新? A:检查是否满足以下条件:

  1. 确保@Model对象类遵循Observable协议
  2. 修改操作需在modelContext的上下文中执行
  3. 主线程规则:所有修改必须在主线程进行

Q:如何强制刷新查询? A:重建查询条件或使用modelContext.refresh(_:)方法:

@State private var refreshFlag = false

@Query(filter: #Predicate<Book> { _ in true }, 
       animation: .default)
var books: [Book]

通过系统化的@Query使用,开发者可以构建出既高效又响应迅速的数据驱动型UI界面。

Last Updated:: 5/30/25, 5:48 PM