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와 관련하여 몇 달 전에 여기에 답변을 게시했습니다.