Najlepsze rozwiązania dotyczące używania FetchedResults do wypełniania selektora SwiftUI

Nov 25 2020

Obecnie pracuję z CoreData FetchedResultsi SwiftUIs PickerView. Robiąc to napotkałem problem podczas używania FetchedResults do wypełnienia PickerView:

Oczywiście mogę użyć FetchedResults do wypełnienia PickerView, ale jakie rozwiązanie jest najlepsze (również z perspektywy UI / UX) do zdefiniowania @State dla wybranego wyniku?

@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)
    }
}

To działa, jednak prawdopodobnie nie jest to najbardziej elegancki sposób tworzenia nowego pustego obiektu użytkownika, aby ustawić go jako domyślny.

Czy ktoś z was ma lepszy pomysł / najlepszą praktykę, aby rozwiązać ten prawdopodobnie często problem?

Odpowiedzi

2 davidev Nov 25 2020 at 17:14

Jeśli nie chcesz cały czas tworzyć fikcyjnego użytkownika (), co nie jest dobrą praktyką, jak wspomniałeś, musisz wykonać swoje FetchRequest w swoim init()lub przekazać FetchedResult do innego widoku.

Oto rozwiązanie z innym widokiem

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?)
            }
        }

    }
}

Edytować:

Właściwie możesz po prostu zadeklarować swoją Osobę jako opcjonalną. Nie musisz więc podawać wartości domyślnej. Podczas pobierania automatycznie przejdzie do pierwszego elementu w selektorze. Jeśli chcesz wybrać inny sposób, możesz użyć powyższej metody. Jeśli chodzi o FetchRequest w init () to napisali odpowiedź kilka miesięcy temu tutaj