SwiftUI и CoreData: как подсчитать количество "истинных" логических значений и отобразить результат в VGrid
Я создал объект CoreData под названием Event
со своими атрибутами category
(Строка) и isBlack
(Булево). Я также создал кнопку и VGrid (бета-версия Xcode 12).
При нажатии кнопки добавляются и сохраняются некоторые записи в CoreData. у меня есть@FetchRequest
и функция update
который возвращает словарь, который группирует записи CoreData по соответствующим категориям. Затем я позволяю VGrid творить чудеса и отображать по одному разделу для каждой категории, используя изображение SFSymbols.
Я хочу добиться того, чтобы VGrid отображал изображение в зависимости от того, сколько "истинных" логических значений находится внутри каждой категории. Итак, если, например, истинные логические значения находятся в большинстве в категории, я хочу отобразитьcircle.filled
, иначе просто circle
.
Вот код, поскольку он использует сетку, он работает только в Xcode 12 (бета):
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Event.entity(),sortDescriptors: []) var events: FetchedResults<Event>
// grouping CoreData entries by categories, returning Dictionary:
func update(_ result : FetchedResults<Event>)-> [[Event]]{
return Dictionary(grouping: result){ (element : Event) in
element.category!
}.values.map{$0}
}
let columns = [
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
var body: some View {
VStack {
Button(action: {
// adding some events in 5 categories, in total 5 grid colums.
let newEvent1 = Event(context: self.moc)
newEvent1.category = "A"
newEvent1.isBlack = true
let newEvent2 = Event(context: self.moc)
newEvent2.category = "A"
newEvent2.isBlack = true
let newEvent3 = Event(context: self.moc)
newEvent3.category = "A"
newEvent3.isBlack = false
let newEvent4 = Event(context: self.moc)
newEvent4.category = "B"
newEvent4.isBlack = false
let newEvent5 = Event(context: self.moc)
newEvent5.category = "C"
newEvent5.isBlack = true
let newEvent6 = Event(context: self.moc)
newEvent6.category = "C"
newEvent6.isBlack = false
let newEvent7 = Event(context: self.moc)
newEvent7.category = "D"
newEvent7.isBlack = true
let newEvent8 = Event(context: self.moc)
newEvent8.category = "D"
newEvent8.isBlack = true
let newEvent9 = Event(context: self.moc)
newEvent9.category = "D"
newEvent9.isBlack = false
let newEvent10 = Event(context: self.moc)
newEvent10.category = "E"
newEvent10.isBlack = true
try? self.moc.save()
}) {
Text("Add some Events")
}
// Grid:
LazyVGrid(columns: columns, spacing: 40) {
ForEach(update(events), id: \.self) { (section: [Event]) in
NavigationLink(destination: Text("this just a test"))
{
// here comes the part i need advice...
// how would i sum up all the true booleans and check if they're the majority in each category?
if section[0].isBlack == true {
Image(systemName: "circle.fill")
} else {
Image(systemName: "circle")
}
// so what i want to achieve is following images being displayed:
// first column (catergory A): circle.filled (cause true booleans are more)
// second column(catergory B): circle
// third column(catergory C): circle.filled (if equal => same as if true)
// fourth column(catergory D): circle
// fifth Column(catergory E): circle.filled
}
}
}
}
}
}
Любая помощь приветствуется, большое спасибо.
1 ответ
Итак, сегодня я понял, как заставить его работать, хотя мне пришлось изменить isBlack?
Boolean в String, а затем уменьшите сгруппированный раздел следующим образом:
let whiteCount = section.reduce(0) { $0 + (($1 as AnyObject).isBlack!.contains("false") ? 1 : 0) }
let blackCount = section.reduce(0) { $0 + (($1 as AnyObject).isBlack!.contains("true") ? 1 : 0) }
Теперь осталось просто сравнить значения whiteCount
а также blackCount
и отобразить соответствующее изображение в сетке.
Я все же предпочел бы решение с логическими значениями.