ItemListView.swift (2715B)
1 import CoreData 2 import SwiftUI 3 4 struct ItemListView: View { 5 let store: ItemStore 6 let syncMonitor: CloudKitSyncMonitor 7 8 @AppStorage("listName") private var listName = "Items" 9 @AppStorage("colorTheme") private var colorThemeRaw = 0 10 private var colorTheme: ColorTheme { ColorTheme(rawValue: colorThemeRaw) ?? .pilbara } 11 12 @FetchRequest( 13 sortDescriptors: [ 14 SortDescriptor(\ItemEntity.sortOrder, order: .forward), 15 ], 16 animation: .default 17 ) 18 private var items: FetchedResults<ItemEntity> 19 20 var body: some View { 21 let activeItems = items.filter { !$0.isCompleted }.map(ItemValue.init) 22 let completedItems = items.filter { $0.isCompleted } 23 .sorted { $0.completedOrder > $1.completedOrder } 24 .map(ItemValue.init) 25 26 NavigationStack { 27 Group { 28 if items.isEmpty { 29 ContentUnavailableView( 30 "No Items", 31 systemImage: "checklist", 32 description: Text("Add items on your iPhone or Mac.") 33 ) 34 } else { 35 List { 36 ForEach(Array(activeItems.enumerated()), id: \.element.id) { index, item in 37 ItemRowView( 38 item: item, 39 index: index, 40 totalActive: activeItems.count, 41 colorTheme: colorTheme, 42 onToggle: { toggleItem($0) } 43 ) 44 } 45 46 if !completedItems.isEmpty { 47 Section("Completed") { 48 ForEach(completedItems) { item in 49 ItemRowView( 50 item: item, 51 index: 0, 52 totalActive: 0, 53 colorTheme: colorTheme, 54 onToggle: { toggleItem($0) } 55 ) 56 } 57 } 58 } 59 } 60 } 61 } 62 .navigationTitle(listName) 63 } 64 } 65 66 private func toggleItem(_ item: ItemValue) { 67 do { 68 if item.isCompleted { 69 try store.uncomplete(itemID: item.id) 70 } else { 71 try store.complete(itemID: item.id) 72 } 73 } catch { 74 // Sync monitor handles error reporting 75 } 76 } 77 }