swift - WidgetKit @StateObject 不更新视图
问题描述
我无法理解如何使我的SwiftUI
数据模型示例与我的小部件一起使用。它在我的测试应用程序中运行良好,我立即观察到变化。View
当我尝试使用小部件时,我可以在控制台中看到正在打印的数据,但我的 in 中没有发生任何变化WidgetKit
。我正在使用一个ObservableObject
类和@Published
变量。我尝试使用 a@StateObject
和@ObservedObject
an@EnvironmentObject
相同的结果。总是导致今天没有比赛。我的数据模型是Combine
相关的,不确定这是否与为什么我看不到.WidgetKit
View
SwiftUI 应用程序示例工作
struct ContentView: View {
@ObservedObject var data = CombineData()
@State private var showSortSheet: Bool = false
@State private var nhlTeams: TeamOrder = .NewYorkIslanders
var body: some View {
NavigationView {
VStack(alignment: .leading) {
if data.schedule?.dates.first != nil {
Text("Game today")
} else {
Text("No game today")
}
}
.listStyle(PlainListStyle())
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarItems(leading: HStack {
Button(action: {
self.showSortSheet.toggle()
}) {
HStack {
Image(systemName: "arrow.up.arrow.down")
}
}
})
.actionSheet(isPresented: $showSortSheet) {
ActionSheet(title: Text("Teams:"), buttons: [TeamOrder.NewYorkIslanders, TeamOrder.MontrealCanadiens].map { method in
ActionSheet.Button.default(Text("\(method.rawValue)")) {
self.nhlTeams = method
data.fetchSchedule(self.nhlTeams.rawValue)
print("\(self.nhlTeams.rawValue)")
}
})
}
.onAppear {
data.fetchSchedule(self.nhlTeams.rawValue)
}
}
}
}
小部件示例@StateObject
(无数据更改)
struct ExampleEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily) var widgetFamily
@StateObject var model = CombineData()
@ObservedObject var model = CombineData()
/*@EnvironmentObject private var model: CombineData*/
var body: some View {
VStack(alignment: .leading) {
if model.schedule?.dates.first != nil {
Text("Game today")
} else {
Text("No game today")
}
}
.onAppear {
model.fetchSchedule(entry.configuration.teams.rawValue) {
WidgetCenter.shared.reloadTimelines(ofKind: "NHL_Widget")
}
}
}
}
示例小部件 2 TimelineEntry(无数据更改)
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationIntent
let model: CombineData
}
struct Provider: IntentTimelineProvider {
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
let currentDate = Date()
let model = CombineData()
let entryDate = Calendar.current.date(byAdding: .minute, value: 1, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration, model: model)
entries.append(entry)
let timeline = Timeline(entries: entries, policy: .atEnd)
model.fetchSchedule(entry.configuration.teams.rawValue) {
completion(timeline)
}
}
}
struct ExampleEntryView : View {
var entry: Provider.Entry
@Environment(\.widgetFamily) var widgetFamily
var body: some View {
VStack(alignment: .leading) {
if entry.model.schedule?.dates.first != nil {
Text("Game today")
} else {
Text("No game today")
}
}
}
}
解决方案
小部件是静态的,您提供的视图getTimeline
将按原样显示并且不会更新,因此对fetchSchedule
on的调用onAppear
甚至不会被执行。一旦在 中执行完成处理程序getTimeline
,就不会再执行任何代码。
要在小部件上显示数据,您需要在 中获取数据getTimeline
,创建一个从一开始就显示数据的视图,并在完成处理程序中返回该条目。
在您的最后一个示例中,我建议您在完成处理程序中创建条目model.fetchSchedule
并将schedule
对象传递给您的视图。
推荐阅读
- ios - 是否可以使用文件系统访问 ios 照片库
- javascript - JS正则表达式在括号前添加一些东西
- c - 递增指向字符串数组的指针返回 NULL
- java - 错误:步骤“发布 JUnit 测试结果报告”失败:未找到测试报告文件。配置错误?
- javascript - 根据浏览器调整输入/输出 div 框大小
- c - 有没有另一种方法来计算没有时钟()的函数执行时间?
- python - conda activate 失败但 shell 提示已更改
- r - R查找列中的值是否超过第二个df的两个时间段之间的阈值
- robotframework - 机器人框架:退出 if 子句但不是关键字?
- javascript - 通过短路分配获取对象的属性