My picker displays an object from CoreData with a sting name and a UUID as tag
I defined the selector of the picker as optional UUID
then currently, during onAppear of the picker, I am initializing the value of selector
the code goes like this:
@State var selectedCollectionId : UUID? = nil
@State var selectedCollection : Collections? = nil
@State var isAllCollectionSelected = false
var body: some View {
ScrollView {
HStack {
Picker("Collections", selection: $selectedCollectionId) {
ForEach(dB.collections) { col in
Text(col.name ?? "No Name").tag(col.id)
}
}.pickerStyle(.menu)
.onChange(of: selectedCollectionId) { newValue in
if let col = dB.collections.first(where: {$0.id == newValue}) {
selectedCollection = col
}
}
.onAppear() {
if(dB.collections.count > 0)
{
selectedCollectionId = dB.collections[0].id
}
}
.disabled(isAllCollectionSelected)
Spacer()
Text("Select All:")
Image(systemName: isAllCollectionSelected ? "checkmark.square" : "square").onTapGesture {
isAllCollectionSelected.toggle()
}
}
// ..... and so on ....
}}
but in the generated code from CoreData there is ? so I guess its optional.
extension Collections {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Collections> {
return NSFetchRequest<Collections>(entityName: "Collections")
}
@NSManaged public var id: UUID?
@NSManaged public var name: String?
@NSManaged public var dateUpdated: Date?
@NSManaged public var hasWords: NSSet?
}
OK if you have unset the Optional then you know that there is going to be a UUID associated with the CoreData record.
That being the case you should put your Picker code inside an if statement and say:
if selectedCollectionId != nil {
// Picker code goes here
}
Also move the .onAppear code to the closing brace of the HStack so that it fires when the HStack is drawn in the View rather than waiting for the Picker View to be drawn. Does that makes sense?
HStack {
if selectedCollectionId != nil {
Picker("Collections", selection: $selectedCollectionId) {
ForEach(dB.collections) { col in
Text(col.name ?? "No Name").tag(col.id)
}
}.pickerStyle(.menu)
.onChange(of: selectedCollectionId) { newValue in
if let col = dB.collections.first(where: {$0.id == newValue}) {
selectedCollection = col
}
}
.disabled(isAllCollectionSelected)
}
Spacer()
Text("Select All:")
Image(systemName: isAllCollectionSelected ? "checkmark.square" : "square").onTapGesture {
isAllCollectionSelected.toggle()
}
}
.onAppear() {
if(dB.collections.count > 0)
{
selectedCollectionId = dB.collections[0].id
}
}
SwiftUI builds the View progressively but it does it blindingly fast so that you don’t see how many times the View is redrawn as each element takes effect.