代码之家  ›  专栏  ›  技术社区  ›  ian

SwiftData-无法转换“谓词表达式”类型的值。相等<谓词表达式。KeyPath<谓词表达式。变量<数组<Todo>。元素>

  •  0
  • ian  · 技术社区  · 11 月前

    在视图中尝试初始化SwiftData查询时,我收到以下错误:

     Error: Cannot convert value of type 'PredicateExpressions.Equal<PredicateExpressions.KeyPath
    <PredicateExpressions.Variable<Array<Todo>.Element>, Int>, PredicateExpressions.KeyPath<PredicateExpressions.Value<Section>, 
    Int>>'(aka'PredicateExpressions.Equal<PredicateExpressions.
    KeyPath<PredicateExpressions.Variable<Todo>, Int>, PredicateExpressions.KeyPath<PredicateExpressions.Value<Section>, 
    Int>>') to closure result type 'any StandardPredicateExpression<Bool>'
    

    TodoView.swift

    import SwiftUI
    import SwiftData
    
    struct TodoView: View {
        
        @Query var todos: [Todo]
        
        @EnvironmentObject var currentSection: Section
        
        @Environment(\.modelContext) var modelContext
        
        var DWMY = ["D","W","M","Y"]
        
        var body: some View {
            List {
                ForEach(todos) { todo in
                    HStack {
                        if todo.completed == false {
                            Text("[ ]")
                        } else {
                            Text("[X]")
                        }
                        Text(todo.name)
                        Text(DWMY[todo.section])
                    }
                }
                .onDelete(perform: deleteToDo)
            }
            .navigationBarTitleDisplayMode(.inline)
        }
        
        init(todoSection: Section) {
            _todos = Query(filter: #Predicate { todo in
                todo.section == currentSection.section
            })
        }
        
        func deleteToDo(at offsets: IndexSet ) {
               for offset in offsets {
                   let todo = todos[offset]
                   modelContext.delete(todo)
               }
        }
    }
    

    当我尝试为查询赋予值时,会出现错误 currentSection.section 如果我更换 当前章节 带有硬编码 Int 没有错误。

    据我所知,这是因为我 环境 不会传递给 ToDoView.swift 直到 车身 是这样创建的 当前章节 在以下情况下不存在 init 发生。

    通过我的正确方式是什么 当前章节 价值进入 init ?

    1 回复  |  直到 11 月前
        1
  •  1
  •   Sweeper    11 月前

    我会做 TodoView 不依赖于环境对象来创建 Query .拿着 init 记下节号。

    struct TodoView: View {
        @Query var todos: [Todo]
    
        // you could still have the EnvironmentObject here for other purposes, just not for creating the query
        // @EnvironmentObject var currentSection: Section
        
        init(sectionNumber: Int) {
            _todos = Query(filter: #Predicate { todo in
                        todo.section == sectionNumber
                    })
        }
        
        var body: some View {
            List(todos) { todo in
                Text(todo.name)
                // ...
            }
        }
    }
    

    然后得到 EnvironmentObject 在父视图中:

    struct TodoWrapper: View {
        @EnvironmentObject var currentSection: Section
    
        var body: some View {
            TodoView(sectionNumber: currentSection.section)
        }
    }