I’ve two selectable lists, the primary is populated with Class
mannequin objects and the second with Subcategory
mannequin objects (that are taken from chosen Class
worth of the primary checklist).
Once I delete an merchandise from the primary checklist, the second checklist doesn’t replace. Here’s a video that exhibits what I imply: https://youtube.com/shorts/VJCe_UK0TNA
I’ve coded the selectable lists in order that the chosen object is retrieved from a computed property binding that returns the item with the latest chosen date:
personal var selectedCategoryBinding: Binding
{
return Binding(get: { self.classes.max(by: { ($0.lastSelectedDate) < ($1.lastSelectedDate) })}, set:{_ in})
}
personal var selectedSubcategoriesBinding: Binding<[Subcategory1]?>
{
Binding<[Subcategory1]?>(get: { self.selectedCategoryBinding.wrappedValue?.subcategories }, set: { self.selectedCategoryBinding.wrappedValue?.subcategories = $0 })
}
I concern that this can be the place the issue lies, however I am uncertain the right way to repair it. Beneath is the whole code. Any assist could be appreciated.
import SwiftUI
import SwiftData
protocol SelectableListItem: Equatable, Identifiable, PersistentModel {
var identify: String { get set }
var lastSelectedDate: Date { get set }
}
@Mannequin
closing class Project1 {
var identify: String = ""
@Relationship(deleteRule: .cascade, inverse: Category1.undertaking) var classes: [Category1]?
init(identify: String) {
self.identify = identify
}
}
@Mannequin
closing class Category1: SelectableListItem {
var identify: String = ""
@Relationship(deleteRule: .cascade, inverse: Subcategory1.class) var subcategories: [Subcategory1]?
var undertaking: Project1?
var lastSelectedDate: Date = Date.now
init(identify: String) {
self.identify = identify
}
}
@Mannequin
closing class Subcategory1: SelectableListItem {
var identify: String = ""
var class: Category1?
var lastSelectedDate: Date = Date.now
init(identify: String) {
self.identify = identify
}
}
struct HomeView: View {
@Setting(.modelContext) personal var modelContext
@Question personal var queriedProjects: [Project1]
var physique: some View {
NavigationStack {
VStack {
Listing {
ForEach(queriedProjects) { undertaking in
if let categoriesBinding = Binding(
Binding<[Category1]?>(
get: { undertaking.classes },
set: { undertaking.classes = $0 }
)
) {
NavigationLink(
vacation spot: ProjectView1(undertaking: undertaking, classes: categoriesBinding),
label: { Textual content(undertaking.identify) }
)
}
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
let undertaking = Project1(identify: "Undertaking 1")
let subcategory1 = Subcategory1(identify: "Subcategory 1")
let subcategory2 = Subcategory1(identify: "Subcategory 2")
let subcategory3 = Subcategory1(identify: "Subcategory 3")
let subcategory4 = Subcategory1(identify: "Subcategory 4")
let category1 = Category1(identify: "Class 1")
category1.subcategories = [subcategory1, subcategory2]
let category2 = Category1(identify: "Class 2")
category2.subcategories = [subcategory3, subcategory4]
undertaking.classes = [category1, category2]
modelContext.insert(undertaking)
} label: {
Label("Plus", systemImage: "plus")
}
}
}
}
.overlay {
if queriedProjects.isEmpty {
Textual content("Faucet the + button to create a brand new undertaking")
}
}
.process {
do {
attempt modelContext.delete(mannequin: Project1.self)
} catch {
fatalError(error.localizedDescription)
}
}
}
.navigationSplitViewStyle(.balanced)
}
}
struct ProjectView1: View {
@Bindable var undertaking: Project1
@Binding var classes: [Category1]
@Setting(.editMode) personal var editMode
@Setting(.modelContext) personal var modelContext
@State personal var columnVisibility: NavigationSplitViewVisibility = .all
personal var selectedCategoryBinding: Binding {
Binding(
get: { classes.max(by: { $0.lastSelectedDate < $1.lastSelectedDate }) },
set: { _ in }
)
}
personal var selectedSubcategoriesBinding: Binding<[Subcategory1]?> {
Binding<[Subcategory1]?>(
get: { selectedCategoryBinding.wrappedValue?.subcategories },
set: { selectedCategoryBinding.wrappedValue?.subcategories = $0 }
)
}
var physique: some View {
NavigationSplitView(columnVisibility: $columnVisibility) {
SelectableList(gadgets: $classes) { class in
class.undertaking = nil
}
if !classes.isEmpty {
if let subcategoriesBinding = Binding(selectedSubcategoriesBinding) {
SelectableList(gadgets: subcategoriesBinding) { subcategory in
subcategory.class = nil
}
}
}
} element: {
EmptyView()
}
}
}
struct SelectableList: View {
@Binding var gadgets: [T]
personal(set) var deleteItem: (T) -> Void
@Setting(.modelContext) personal var modelContext
@Question personal var queriedItems: [T]
personal var filteredAndSortedItems: [T] {
queriedItems
.filter { gadgets.incorporates($0) }
.sorted { $0.identify.localizedCaseInsensitiveCompare($1.identify) == .orderedAscending }
}
personal var selectedItem: T? {
filteredAndSortedItems.max(by: { $0.lastSelectedDate < $1.lastSelectedDate })
}
var physique: some View {
Listing {
ForEach(filteredAndSortedItems) { merchandise in
HStack {
Button {
if selectedItem != merchandise {
merchandise.lastSelectedDate = .now
}
} label: {
Textual content(merchandise.identify)
}
.buttonStyle(PlainButtonStyle())
if selectedItem == merchandise {
Picture(systemName: "checkmark")
}
Spacer()
Button {
deleteItem(merchandise)
modelContext.delete(merchandise)
} label: {
Picture(systemName: "trash")
}
}
}
}
}
}