如何在WidgetKit,SwiftUI的午夜更改视图?

问题描述

我有一个代码

struct ContentView: View {
    let entry: LessonWidgetEntry
    private static let url: URL = URL(string: "widgetUrl")!
    var body: some View {
        vstack {
            switch entry.state {
            case .none:
                ProgramNotStartedView()
            case .currentLesson(let lesson):
                LessonView(lesson: lesson,imageName: entry.program?.imageName)
            case .lessonCompleted(let lesson):
                LessonCompletedView(lesson: lesson)
            case .programCompleted:
                ProgramCompletedView()
            }
        }.widgetURL(ContentView.url)
    }
}

在午夜,LessonCompletedView应该更改为LessonView,但是我不确定该怎么做。 关于如何通过小部件在午夜更改视图的任何想法?

解决方法

  1. 假设您有一个条目(在您的应用中,您有entry.state...,但在此示例中,我使用的是简化版本):
struct SimpleEntry: TimelineEntry {
    let date: Date
    let lesson: Lesson
}
  1. 将您的TimelineProvider设置为在下一个午夜之后刷新时间轴:
struct SimpleProvider: TimelineProvider {
    ...

    func getTimeline(in context: Context,completion: @escaping (Timeline<Entry>) -> Void) {
        let currentDate = Date()
        let midnight = Calendar.current.startOfDay(for: currentDate)
        let nextMidnight = Calendar.current.date(byAdding: .day,value: 1,to: midnight)!

        let entries = [
            SimpleEntry(date: entryDate,lesson: Lesson()) // pass the lesson here
        ]

        let timeline = Timeline(entries: entries,policy: .after(nextMidnight))
        completion(timeline)
    }
}

在TimelineProvider中,您可以通过任何所需的课程(取决于当天或上一课程-由您决定)。您还可以将变量传递给Entry,以指示课程是否完成。

通过设置.after(nextMidnight)策略,您可以指定何时希望重新加载时间轴(从而使小部件视图)。