ios Swift/Widget扩展-每秒更新时间

1hdlvixo  于 2023-04-22  发布在  iOS
关注(0)|答案(1)|浏览(291)

这是我的第一篇文章,所以让我知道如果需要更多的信息。
我正在创建一个小部件,它将同时显示两个位置的当前时间。
这是我现在的代码:

import SwiftUI
import WidgetKit

struct TimeWidgetView: View {
    var localTime: String
    var foreignTime: String
    
    var body: some View {
        HStack(spacing: 16) {
            VStack{
                Text("Local Time")
                    .font(.title2)
                    .fontWeight(.bold)
                    .foregroundColor(.primary)
                
                Text(localTime)
                    .font(.title3)
                    .fontWeight(.semibold)
                    .foregroundColor(.primary)
                    .multilineTextAlignment(.center)
                    .lineLimit(1)
                    .minimumScaleFactor(0.7)
            }
            
            VStack{
                Text("China Time")
                    .font(.title2)
                    .fontWeight(.bold)
                    .foregroundColor(.primary)
                
                Text(foreignTime)
                    .font(.title3)
                    .fontWeight(.semibold)
                    .foregroundColor(.primary)
                    .multilineTextAlignment(.center)
                    .lineLimit(1)
                    .minimumScaleFactor(0.7)
            }
            
        }
        .padding()
    }
}

struct TimeWidget: Widget {
    private let kind: String = "TimeWidget"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: TimeProvider()) { entry in
            TimeWidgetView(localTime: entry.localTime, foreignTime: entry.foreignTime)
        }
        .configurationDisplayName("Time Widget")
        .description("Displays local time and China time.")
    }
}

struct TimeProvider: TimelineProvider {
    func placeholder(in context: Context) -> TimeEntry {
        TimeEntry(localTime: "00:00", foreignTime: "00:00")
    }

    func getSnapshot(in context: Context, completion: @escaping (TimeEntry) -> Void) {
        let entry = TimeEntry(localTime: "12:34", foreignTime: "23:34")
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<TimeEntry>) -> Void) {
        let currentDate = Date()
        let calendar = Calendar.current
        
        let localTimeFormatter = DateFormatter()
        localTimeFormatter.dateFormat = "HH:mm:ss"
        let localTime = localTimeFormatter.string(from: currentDate)
        
        let foreignTimeFormatter = DateFormatter()
        foreignTimeFormatter.timeZone = TimeZone(identifier: "Asia/Shanghai") // Set time zone to China
        foreignTimeFormatter.dateFormat = "HH:mm:ss"
        let foreignTime = foreignTimeFormatter.string(from: currentDate)
        
        let entry = TimeEntry(localTime: localTime, foreignTime: foreignTime)
        let timeline = Timeline(entries: [entry], policy: .atEnd)
        completion(timeline)
    }
}

struct TimeEntry: TimelineEntry {
    var date: Date = Date()
    var localTime: String
    var foreignTime: String
}

struct TimeWidget_Previews: PreviewProvider {
    static var previews: some View {
        TimeWidgetView(localTime: "12:34:56", foreignTime: "23:34:45")
            .previewContext(WidgetPreviewContext(family: .systemMedium))
    }
}

当我从Xcode运行应用程序/小部件时,它显示正确的时间,但时间没有改变..我不明白我如何才能做到这一点。
我怎样才能使它每秒更新一次,这样它就能像数字时钟一样工作了?
编辑:我可能找到了一个解决方案,但不确定这是否是一个好方法(考虑电池寿命):

func getTimeline(in context: Context, completion: @escaping (Timeline<TimeEntry>) -> Void) {
        var entries: [TimeEntry] = []
        
        // Use a Timer to update the widget every half second as a clock
        let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        for second in 0...59 {
            let currentDate = Date().addingTimeInterval(TimeInterval(second))
            
            let localTime = formatter.string(from: currentDate)
            
            let foreignTimeFormatter = DateFormatter()
            foreignTimeFormatter.timeZone = TimeZone(identifier: "Asia/Shanghai") // Set time zone to China
            foreignTimeFormatter.dateFormat = "HH:mm:ss"
            let foreignTime = foreignTimeFormatter.string(from: currentDate)
            
            let entry = TimeEntry(date: currentDate, localTime: localTime, foreignTime: foreignTime)
            entries.append(entry)
        }
        
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
tf7tbtn2

tf7tbtn21#

请查看Apple的官方文档:https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date
我认为如果你试图绕过限制,你可能只会得到“惩罚”,你的小部件将更新更不频繁。
我还检查了是否可以在你的小部件中实现动画,这样你就可以实现一个移动的时钟指针,它基本上是自己移动的,而不需要每秒钟手动更新它,但这也不起作用,因为WidgetKit中没有动画。所以,是的,我认为你想要实现的是不可能的。

相关问题