使用FetchedResults填充SwiftUI选择器的最佳实践

使用FetchedResults填充SwiftUI选择器的最佳实践,swift,core-data,swiftui,init,picker,Swift,Core Data,Swiftui,Init,Picker,我目前正在使用coredatafetchedresults和SwiftUIs PickerView。在执行此操作时,我在使用FetchedResults填充PickerView时遇到了一个问题: 显然,我可以使用FetchedResults来填充PickerView,但是对于为所选结果定义@State,哪种解决方案是最好的(也是从UI/UX的角度来看) @FetchRequest(sortDescriptors:[NSSortDescriptor(keyPath:\User.lastName,升

我目前正在使用
coredatafetchedresults
SwiftUIs PickerView
。在执行此操作时,我在使用FetchedResults填充PickerView时遇到了一个问题:

显然,我可以使用FetchedResults来填充PickerView,但是对于为所选结果定义@State,哪种解决方案是最好的(也是从UI/UX的角度来看)

@FetchRequest(sortDescriptors:[NSSortDescriptor(keyPath:\User.lastName,升序:true)],动画:。默认)私有变量用户:FetchedResults
@状态变量user:user=user()
// ...
选择器(选择:$user,标签:Text(“user”)){
ForEach(用户){user in
Text(lastName).tag(用户)
}
}
这确实有效,但是创建一个新的空用户对象并将其设置为默认值可能不是最优雅的方法


有谁有更好的想法/最佳实践来解决这个可能经常出现的问题吗?

如果您不想一直创建一个伪用户(),正如您所提到的,这不是一个好的实践,那么您必须在
init()
中执行FetchRequest,或者将FetchedResult传递到另一个视图

下面是另一个视图的解决方案

struct ContentView : View {
    
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \User.lastName, ascending: true)], animation: .default) private var users: FetchedResults<User>

    var body : some View {
        PickerView(users: Array(users))
    }
}

struct PickerView : View {

    var users : [User]
    @State var selectedUser : User?
    
    init(users: [User]) {
        self.users = users
        self._selectedUser = State(initialValue: users.first)
    }
    
    var body : some View {
        Picker(selection: $selectedUser, label: Text("Users")) {
            ForEach(users) { user in
                Text(user.lastName ?? "").tag(user as User?)
            }
        }

    }
}
struct ContentView:View{
@FetchRequest(SortDescriptor:[NSSortDescriptor(keyPath:\User.lastName,升序:true)],动画:。默认值)私有变量用户:FetchedResults
var body:一些观点{
PickerView(用户:数组(用户))
}
}
结构PickerView:视图{
var用户:[用户]
@状态变量selectedUser:用户?
初始化(用户:[用户]){
self.users=用户
self.\u selectedUser=State(初始值:users.first)
}
var body:一些观点{
选择器(选择:$selectedUser,标签:文本(“用户”)){
ForEach(用户){user in
文本(user.lastName???).tag(用户身份?)
}
}
}
}
编辑:


实际上,您可以将您的人员声明为可选。因此,您不必提供默认值。提取时,它将自动移动到选择器中的第一个项目。如果您希望选择不同的方法,可以使用上述方法。关于init()中的FetchRequest,它在几个月前发布了一个答案

您可以使用用户对象以外的其他对象进行标记,例如用户的唯一属性感谢您的帮助,这看起来是解决此问题的一个很好的方法。您还可以为第二个选项(在init()中)提供解决方案吗?那太好了。当然,让我检查一下我的项目。只需几分钟将您的人员声明为可选实际上会起作用,这是最简单的解决方案。将用户设置为可选并不会引发错误,但会阻止我在选择器列表中选择条目。我可以打开选择器并查看FetchedResult的所有条目,但我无法选择一个。解决了它。您必须在.tag修饰符->.tag(用户身份?)中强制转换数据类型。你能把这个加到你的答案里吗?