【问题标题】:Cannot convert value of type 'Published<[StepsEntity]>.Publisher' to expected argument type 'Binding<String>'无法将“Published<[StepsEntity]>.Publisher”类型的值转换为预期的参数类型“Binding<String>”
【发布时间】:2021-09-09 16:45:53
【问题描述】:

StepsEntity 是核心数据实体

尝试在 TextField 中显示字符串值时收到以下错误:“无法将 'Published.Publisher' 类型的值转换为预期的参数类型 'Binding'”

我知道这是因为我的核心数据模型中的 StepsEntity 是 @Published。 @Published 在这里工作得很好,因为它允许整齐地更新所有数据。如何在 TextField 中显示 @Published?

以下是我收到错误的部分:

List {
            VStack(alignment: .center) {
                if let recipeSteps = (vm.recipes[vm.getRecordsCount() - 1].steps?.allObjects as? [StepsEntity])?.sorted { $0.stepNumber < $1.stepNumber } {
                    
                    if (textFieldCount == 1) {
                        //do nothing
                    } else if (textFieldCount > 1) {
                        ForEach(recipeSteps, id: \.stepNumber) { index in
                            HStack {
                               
                                Text(String(index.stepNumber) + ".").bold()
                                TextField("", text: vm.$recipeSteps) //This is where the error is seen
                                
                            }
                        }.onDelete(perform: { index in
                            self.vm.deleteRecipeSteps(at: index, from: vm.recipes[vm.getRecordsCount() - 1])
                            })
                    }
                
                }
            }

vm.recipeSteps 指的是我的 CoreDataRelationshipViewModel,它是处理所有核心数据函数的地方。这在视图结构中声明为:

@StateObject var vm = CoreDataRelationshipViewModel()

这是来自 CoreDataRelationshipViewModel 类的 sn-p:

class CoreDataRelationshipViewModel: ObservableObject {

let manager = CoreDataManager.instance
@Published var recipes: [RecipeEntity] = []
@Published var recipeSteps: [StepsEntity] = []

init() {
    getRecipes()
}

func getRecipes() { ////more functions for retrieving, deleting, etc. in this section

我尝试将 Published var 转换为绑定,但没有成功:

TextField("", text: Binding(vm.$recipeSteps)!)

我也尝试在列表中引用 if let 语句中声明的 recipeSteps,但这也不起作用。

我已经用了几天了,我想我已经用尽了所有的选择。在这里接受所有想法。也许我需要重建我的模型?

想法?

--编辑--

结构的上部,创建变量的地方:

struct AddItemView: View {

@StateObject var viewModel = ViewModel()
@State var frameDimensions: CGFloat = 0
@State var imageButtonText: String = "Click To Add Image"
@State var imageToUpload: Data

@StateObject var vm = CoreDataRelationshipViewModel()
@Environment(\.presentationMode) var presentationMode
@State var stepInfo: String = ""
@State var textFieldCount: Int = 1
@State var stepNumber: [Int]
@State var recordsCount = 1
@State var errorText = ""
@State var stepErrorColor = Color.white.opacity(0)
@State var nameErrorColor = Color.white.opacity(0)

var body: some View {
    ZStack {
        HStack {

【问题讨论】:

  • TextField 期望绑定到 String,因为它会根据包含的字符串通过该绑定更新属性。当您尝试更新 recepeSteps 时,您要完成什么,这是一些对象的数组
  • 最终目标是如果用户更新文本字段列表中的项目,更新后的值将替换 CoreData 中的原始值。想想一个待办事项清单,你创建了一个待办事项清单,然后你意识到你打错了。作为用户,我会回去编辑拼写错误。然后更新应保存到核心数据。目前专注于首先返回文本字段中的值,然后将处理保存到核心数据的更新。
  • 当然,但是您正在尝试创建与数组的绑定,而不是与字符串属性的绑定。 TextField 只能更新字符串属性。也许您想更新单个项目。然后你需要这样的东西:TextField("", text: $vm.recepeSteps[index].someStringProp) 其中someStringProp 是你正在更新的属性

标签: swift swiftui binding combine


【解决方案1】:

你的问题是

TextField("", text: vm.$recipeSteps)

应该是

TextField("", text: $vm.recipeSteps)

因为您需要使用 Binding 而不是 recipeSteps 传递视图模型(当使用 $ 将其传递到 vm 的点访问器之外时,传递一个通用的 Publisher)。

此外,这仅在您的视图模型中的 @Published 属性符合 StringProtocol(是一个字符串)时才有效。你确定recipeSteps是一个可以通过TextField编辑的字符串吗?

【讨论】:

  • 我看到一个问题,它在范围内找不到“$vm”。是否需要做一些额外的事情才能让它发挥作用?此外,recipesteps 可能是一个包含字符串值的 NSSet。这会改变方法吗? --编辑,它是“公共类 StepsEntity : NSManagedObject” - 看起来它是一个 NSManagedObject
  • 如果 @StateObject var vm = CoreDataRelationshipViewModel() 在您的列表视图中被调用,那么 vm 应该出现在范围内。老实说,我不确定TextFields 是否可以与NSSet 的字符串一起使用,但是如果在整理出您的vm 后它没有抛出错误,那么我想它会很好。也许该数组中的元素由 TextField 中的换行符分隔。
  • 目前没有分隔数据的新行。 “vm”确实出现在范围内,但“$vm”没有。可能是因为文本字段需要字符串绑定,但我将它传递给 nsmanagedobject?
  • 我觉得奇怪的是$vm 没有出现在范围内。您能否编辑您的帖子以在您的 View 结构中包含 vm 的声明?也许我们可以通过这种方式获得更全面的了解。 [编辑:谢谢!]
  • 添加了结构的顶部。如果您需要更多信息,请告诉我。
【解决方案2】:

我最终重组了我的核心数据保存工作方式。我现在不是逐项保存,而是循环通过 for in 循环来最后保存所有数据。这允许我通过一些状态变量在本地显示数据,然后将完整的数组保存到我的核心数据实体中。

【讨论】:

    猜你喜欢
    • 2020-11-26
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    相关资源
    最近更新 更多