首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WidgetKit @StateObject不更新视图

WidgetKit @StateObject不更新视图
EN

Stack Overflow用户
提问于 2021-03-26 09:04:47
回答 1查看 603关注 0票数 1

我很难理解如何使我的SwiftUI数据模型示例与我的Widget一起工作。它在我的测试应用程序中运行得很好,我立即观察到变化。当我尝试使用Widget时,我可以看到控制台中正在打印数据,但是在我的ViewWidgetKit中没有发生任何更改。我使用的是ObservableObject类和@Published变量。我尝试使用@StateObject@ObservedObject@EnvironmentObject以及相同的结果。今天总是没有比赛。我的数据模型与Combine相关,不确定这是否与为什么我无法在WidgetKitView中看到数据变化有关。

SwiftUI应用程序示例工作

代码语言:javascript
复制
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)
            }
        }
    }
}

示例Widget (无数据更改)

代码语言:javascript
复制
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")
            }
        }
    }
}

示例Widget 2 TimelineEntry (无数据更改)

代码语言:javascript
复制
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")
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-26 09:17:25

小部件是静态的,您在getTimeline上提供的视图将按原样显示,不会被更新,因此对fetchSchedule on onAppear的调用甚至不会被执行。在getTimeline中执行完成处理程序后,不再执行代码。

要在小部件上显示数据,需要在getTimeline中获取数据,创建一个从一开始就显示数据的视图,并在完成处理程序中返回该条目。

在最后一个示例中,我建议您在model.fetchSchedule的完成处理程序中创建条目,并将schedule对象传递给视图。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66813851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档