按日期实时更新视图/SwiftUI

问题描述 投票:0回答:2

我想知道您是否可以帮我解决 SwiftUI 问题。具体来说,我试图在午夜或日期更改时更新我的视图中的 ForEach 循环。我的模型中的所有日期均采用“dd.MM.yyyy”格式,并按日期提取到 ForEach 循环。如何实时更改日期或在午夜用新事件重新加载 ForEach 循环? 任何提示或建议将不胜感激!


虚拟机


import Foundation

@MainActor
final class TodaysEventsViewModel: ObservableObject {
    
    @Published var events = [EventModel]()
    @Published var event = [Event]()
    
    @Published var selectedEvent: Event?
    
    @Published var date = Date()
    
    private var stringDate: String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "dd.MM.yyyy"
        let currentDateString = dateFormatter.string(from: date)
        return currentDateString
    }
    
    init() {
        fetchEvents()
        getTodaysEvents()
    }
    
    private func fetchEvents() {
        let eventsData = Bundle.main.decode([EventModel].self, from: "EventsData.json")
        events = eventsData
    }
    
    private func getTodaysEvents() {
        if let index = events.first(where: {$0.date == stringDate}) {

        event = index.event

        }
    }
}

查看


import SwiftUI

struct TodaysEventsView: View {
    
    @StateObject private var viewModel = TodaysEventsViewModel()
    
    var body: some View {
        
        VStack(spacing: 7.5) {
            ForEach(viewModel.event, id: \.id) { event in
                Button {
                    self.viewModel.selectedEvent = event
                } label: {
                    EventCell(event: event)
                }
            }
        }
        .sheet(item: $viewModel.selectedevent) { event in
            EventDetailView(event: event)
        }
    }
}
swift date swiftui mvvm view
2个回答
3
投票

您可以使用

notifications
异步序列,在
for
 视图修改器中启动 
await
-in
-
.task
循环:

struct ContentView: View {
    @StateObject var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            … 
        }
        .task {
            await viewModel.monitorDateChanges()
        }
    }
}

@MainActor
class ViewModel: ObservableObject {
    …
    
    nonisolated func monitorDateChanges() async {
        let notifications = NotificationCenter.default.notifications(named: .NSCalendarDayChanged)
        
        for await _ in notifications {
            …
        }
    }
}

注意,使用

.task
视图修饰符,“SwiftUI 将在视图消失后的某个时刻自动取消任务......”。因此,当视图关闭时,这个循环将自动取消。


2
投票

您可以观察日历中的日期变化,例如:

struct ContentView: View {
    let publisher = NotificationCenter.default.publisher(for: .NSCalendarDayChanged)

    var body: some View {
        Text("Hello World")
            .onReceive(publisher) { output in
                print(output) // 👈 Perform your task here
            }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.