โ—return Binding

SwiftUI โŸฉ Data Flow โŸฉ Binding โŸฉ return Binding

๐Ÿ“— ๅƒ่€ƒ๏ผšSwift Playgrounds (Date Planner - Event Data)

class EventData: ObservableObject {

    @Published var events: [Event] = [ ... ]
    
    // omitted ...
    
    // โญ๏ธ ็ฅžๅฅ‡็š„ method๏ผš
    // 1. ๅ›žๅ‚ณ็š„ๅž‹ๅˆฅๆ˜ฏ Binding<[Event]>
    // 2. Binding<[Event]>(get: {}, set: {}) ่ชžๆณ•โ—๏ธโ—๏ธโ—๏ธ
    //                                   โ•ญโ”€โ”€โ”€โ”€ โญ๏ธ 1 โ”€โ”€โ”€โ”€โ•ฎ
    func sortedEvents(period: Period) -> Binding<[Event]> {
    //  โ•ญโ”€โ”€โ”€โ”€ โญ๏ธ 2 โ”€โ”€โ”€โ”€โ•ฎ
        Binding<[Event]>(
        
            // โญ๏ธ get: read binding data
            get: {
                self.events
                    .filter {
                        switch period {
                        case .nextSevenDays:
                            return $0.isWithinSevenDays
                        case .nextThirtyDays:
                            return $0.isWithinSevenToThirtyDays
                        case .future:
                            return $0.isDistant
                        case .past:
                            return $0.isPast
                        }
                    }
                    .sorted { $0.date < $1.date }
            },
            
            // โญ๏ธ set: write binding data
            set: { events in
                for event in events {
                    if let index = self.events.firstIndex(where: { $0.id == event.id }) {
                        self.events[index] = event
                    }
                }
            }
            
        )// end: Binding<[Event]>()
    }// end: sortedEvents()
}

ๅฆ‚ไฝ•ไฝฟ็”จๅ‚ณๅ›ž็š„ Binding<[Event]>๏ผš

struct EventList: View {

    @EnvironmentObject var eventData: EventData
    @State private var isAddingNewEvent = false
    @State private var newEvent = Event()
    
    var body: some View {
        
        List {
            ForEach(Period.allCases) { period in

                if !eventData.sortedEvents(period: period).isEmpty {
                    Section(content: {
                        //      โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€ โญ๏ธ Binding<[Event]> โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ    โ•ญโ”€โญ๏ธโ”€โ•ฎ
                        ForEach(eventData.sortedEvents(period: period)) { $event in
                        //                                             โญ๏ธ โ†ฒ
                            NavigationLink {
                                // two-way binding โ•ญโ”€โญ๏ธโ”€โ•ฎ
                                EventEditor(event: $event)
                            } label: {
                                // one-way      โ•ญโญ๏ธโ”€โ•ฎ
                                EventRow(event: event)
                            }
                            .swipeActions {
                                Button(role: .destructive) {
                                    eventData.delete(event)
                                } label: {
                                    Label("Delete", systemImage: "trash")
                                }
                            }
                        }
                    }, header: {
                        Text(period.name)
                            .font(.callout)
                            .foregroundColor(.secondary)
                            .fontWeight(.bold)
                    })
                }
            }
        }
        .navigationTitle("Date Planner")
        .toolbar {
            ToolbarItem {
                Button {
                    newEvent = Event()
                    isAddingNewEvent = true
                } label: {
                    Image(systemName: "plus")
                }
            }
        }
        .sheet(isPresented: $isAddingNewEvent) {
            NavigationView {
                EventEditor(event: $newEvent, isNew: true)
            }
        }
    }
}

Last updated