use*_*291 6 widget swift widgetkit swiftui ios14
我正在为 ios 14 Home Widget 开发一个应用程序,在显示当前时间(数字时钟)时遇到一个问题,即该小部件没有每秒更新。众所周知,苹果不允许每秒触发时间线,有没有其他方法可以实时更新显示当前时间?
我尝试了这些方法,但没有按预期工作
class NetworkManager: ObservableObject {
@Published var dateIs = Date()
init() {
startTimer() // fetch data must be called at least once
}
private func startTimer() {
let t = RepeatingTimer(timeInterval: 3)
t.eventHandler = {
DispatchQueue.main.async() {
// your UI update code
print("Timer Fired")
self.dateIs = Date()
WidgetCenter.shared.reloadAllTimelines() // reload timelines
}
if(false){ //I know this makes no sense, but it works. Go figure...
t.suspend()
}
}
t.resume()
}
}
struct Provider: TimelineProvider {
init() {
networkManager = NetworkManager()
}
@AppStorage("storedData", store: UserDefaults(suiteName: "group.com.name"))
var data: Data = Data()
func placeholder(in context: Context) -> WidgetEntry {
let entry = WidgetEntry(date: Date(), storedData: storedData[0], dateIs: networkManager.dateIs)
return entry
}
func getSnapshot(in context: Context, completion: @escaping (WidgetEntry) -> Void) {
guard let storedData: WidgetTemplate = try? JSONDecoder().decode(WidgetTemplate.self, from: data) else { return }
let entry = WidgetEntry(date: Date(), storedData: storedData, dateIs: networkManager.dateIs)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WidgetEntry>) -> Void) {
guard let storedData: WidgetTemplate = try? JSONDecoder().decode(WidgetTemplate.self, from: data) else { return }
let entry = WidgetEntry(date: Date(), storedData: storedData, dateIs: networkManager.dateIs)
let currentDate = Date()
let refreshDate = Calendar.current.date(byAdding: .minute, value: 5, to: currentDate)!
let timeline = Timeline(entries: [entry], policy: .after(refreshDate))
completion(timeline)
}
}
Run Code Online (Sandbox Code Playgroud)
您\xe2\x80\x99 不允许每秒刷新该Widget 。那\xe2\x80\x99是Apple的限制。
\n您能做的最好的事情就是使用日期样式显示带秒的timer日期:
/// A style displaying a date as timer counting from now.\n///\n/// Text(event.startDate, style: .timer)\n///\n/// Example output:\n/// 2:32\n/// 36:59:01\npublic static let timer: Text.DateStyle\nRun Code Online (Sandbox Code Playgroud)\nEntry属性Date:struct SimpleEntry: TimelineEntry {\n let date: Date\n}\nRun Code Online (Sandbox Code Playgroud)\nEntry后刷新时间线:struct SimpleProvider: TimelineProvider {\n ...\n\n func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {\n let midnight = Calendar.current.startOfDay(for: Date())\n let nextMidnight = Calendar.current.date(byAdding: .day, value: 1, to: midnight)!\n let entries = [SimpleEntry(date: midnight)]\n let timeline = Timeline(entries: entries, policy: .after(nextMidnight))\n completion(timeline)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\ntimer:struct SimpleWidgetEntryView: View {\n var entry: SimpleProvider.Entry\n\n var body: some View {\n Text(entry.date, style: .timer)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n请注意,当您刷新时间线(通过指定TimelineReloadPolicy或通过调用WidgetCenter)时,您设置了刷新 Widget 的最早时间。
不保证在该特定时间刷新。
\n| 归档时间: |
|
| 查看次数: |
5798 次 |
| 最近记录: |