【问题标题】:How to display Current Time (Realtime) in iOS 14 Home Widget如何在 iOS 14 Home Widget 中显示当前时间(实时)
【发布时间】:2021-01-11 03:34:45
【问题描述】:

我正在为 ios 14 Home Widget 开发应用程序,但在显示当前时间(数字时钟)时遇到问题,该小部件没有每秒更新一次。众所周知,Apple 不允许每秒触发时间轴,还有其他方法可以通过实时更新显示当前时间吗?

我尝试了这些方法,但没有按预期工作

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)
    }
    
}

【问题讨论】:

标签: swift swiftui widget ios14 widgetkit


【解决方案1】:

您不能每秒刷新 Widget。这就是 Apple 的限制。

你能做的最好的就是用显示一个日期 使用timer 日期样式:

/// A style displaying a date as timer counting from now.
///
///     Text(event.startDate, style: .timer)
///
/// Example output:
///    2:32
///    36:59:01
public static let timer: Text.DateStyle

  1. 您需要一个简单的 EntryDate 属性:
struct SimpleEntry: TimelineEntry {
    let date: Date
}
  1. Entry 中传递给定日期的午夜日期,并在下一个午夜之后刷新时间线:
struct SimpleProvider: TimelineProvider {
    ...

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        let midnight = Calendar.current.startOfDay(for: Date())
        let nextMidnight = Calendar.current.date(byAdding: .day, value: 1, to: midnight)!
        let entries = [SimpleEntry(date: midnight)]
        let timeline = Timeline(entries: entries, policy: .after(nextMidnight))
        completion(timeline)
    }
}
  1. 使用timer 样式显示日期:
struct SimpleWidgetEntryView: View {
    var entry: SimpleProvider.Entry

    var body: some View {
        Text(entry.date, style: .timer)
    }
}

请注意,当您刷新时间线时(通过指定 TimelineReloadPolicy 或通过调用 WidgetCenter),您设置了 最早 小部件的时间刷新。

不保证在特定时间刷新

【讨论】:

  • 这可以用作计时器,但不能用作时钟。时钟的格式为“hh:mm”,但这里我的格式为“mm:ss”。现在思考如何从这些获取时钟格式
  • @Maks 我添加了一个答案here
  • @pawello2222 是的,非常完美。但现在我无法通过调用 WidgetCenter.shared.reloadAllTimelines() 来使用文本颜色背景图像等新数据刷新小部件
  • @user3634291 不允许每秒刷新 Widget。这就是苹果的限制。你能做的最好的就是用秒显示日期。
  • @myatmins 您可以选择不同的样式:timedaterelativeoffsettimer。但我不认为您可以自定义样式 - 您可以尝试混合它们(例如,通过显示两个文本彼此相邻)。
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2022-08-20
  • 2021-01-31
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多