SwiftUIピッカーにデータを入力するためにFetchedResultsを使用するためのベストプラクティス

Nov 25 2020

私は現在で働いていますCoreData FetchedResultsSwiftUIs PickerView。そうしているときに、FetchedResultsを使用してPickerViewにデータを入力するときに問題が発生しました。

明らかにFetchedResultsを使用してPickerViewにデータを入力できますが、選択した結果の@Stateを定義するために(UI / UXの観点からも)最適なソリューションはどれですか?

@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \User.lastName, ascending: true)], animation: .default) private var users: FetchedResults<User>
@State var user: User = User()

// ...

Picker(selection: $user, label: Text("User")) {
    ForEach(users) { user in
        Text(lastName).tag(user)
    }
}

これは機能しますが、新しい空のユーザーオブジェクトを作成してデフォルトとして設定するのにおそらく最も洗練された方法ではありません

このおそらくしばしば問題を解決するためのより良いアイデア/ベストプラクティスを持っている人はいますか?

回答

2 davidev Nov 25 2020 at 17:14

ダミーのUser()を常に作成したくない場合(これは、前述のように適切な方法ではありません)、でFetchRequestを実行するinit()か、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?)
            }
        }

    }
}

編集:

実際には、Personをオプションとして宣言することができます。したがって、デフォルトを指定する必要はありません。フェッチすると、ピッカーの最初のアイテムに自動的に移動します。別の方法で選択したい場合は、上記の方法を使用できます。init()のFetchRequestに関しては、数か月前にここに回答を投稿しました