这是我的第一篇文章,所以让我知道如果需要更多的信息。
我正在创建一个小部件,它将同时显示两个位置的当前时间。
这是我现在的代码:
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)
}
1条答案
按热度按时间tf7tbtn21#
请查看Apple的官方文档:https://developer.apple.com/documentation/widgetkit/keeping-a-widget-up-to-date
我认为如果你试图绕过限制,你可能只会得到“惩罚”,你的小部件将更新更不频繁。
我还检查了是否可以在你的小部件中实现动画,这样你就可以实现一个移动的时钟指针,它基本上是自己移动的,而不需要每秒钟手动更新它,但这也不起作用,因为WidgetKit中没有动画。所以,是的,我认为你想要实现的是不可能的。