核心数据值检查 - SwiftUi

Core Data value check - SwiftUi

伙计们。

我的 WatchOS 应用允许创建目标。如果标题之前在其他目标中使用过,或者用户在文本字段中未输入任何内容,我将尝试禁用该按钮。

所以我试图获取我的数据,并写了.disabled(goalTitle == item.goalTitle)。但是它会导致问题,如果没有创建目标,按钮就会消失。在其他情况下,输入存在的标题后,它会复制按钮 - 一个已禁用,一个正在工作。

这是我的视图代码:

struct AddGoalView: View {
@State private var goalTitle = ""
@FetchRequest (
entity:NewGoal.entity(),
   sortDescriptors:[NSSortDescriptor(keyPath: \NewGoal.dateAdded, ascending: false)],
    animation: .easeInOut )

var results:FetchedResults<NewGoal>

@Environment(\.managedObjectContext) var context
@Environment(\.presentationMode) var presentationMode

var body: some View {
    ScrollView{
    VStack (alignment: .leading, spacing: 6){
    TextField("Goal Name...", text: $goalTitle)
            .padding(.bottom)

        ForEach(results){item in ///---> This leads to the Button duplicating
        Button(action: addGoal) {
            Text("Add Goal")
            
        }
        .frame(maxWidth: .infinity, alignment: .center)
        .disabled(goalTitle == "")
        .disabled(goalTitle == item.goalTitle) ///---> Here I am trying to disable a button when the user writes down the existed title, to prevent Goal duplicates. 
        }
    }
}
}
private func addGoal(){
    let goal = NewGoal(context: context)
    goal.goalTitle = goalTitle
    goal.dateAdded = Date()
    do{
        try context.save()
        presentationMode.wrappedValue.dismiss()
    }catch let err{
        print(err.localizedDescription)
        }
    }
}

您可以在 results 上使用 .contains(where:) 来确定是否已经有使用该标题的目标,而不是使用 ForEach 来遍历您的元素:

var body: some View {
    ScrollView{
        VStack (alignment: .leading, spacing: 6){
            TextField("Goal Name...", text: $goalTitle)
                .padding(.bottom)
            
            Button(action: addGoal) {
                Text("Add Goal")
            }.disabled(
                goalTitle.isEmpty ||
                results.contains(where: { [=10=].goalTitle == goalTitle})
            )
        }
    }
}