返回

SwiftUI WidgetKit 如何显示「下午 2:30」时间格式?

IOS

摆脱 SwiftUI WidgetKit 时间显示困境:用「下午 2:30」格式告别「14:30:25」

在 SwiftUI Widget 中使用 timer 样式显示时间时,你是否也曾被「14:30:25」这样的 24 小时制困扰,而无法实现更符合用户习惯的「下午 2:30」格式?

你可能尝试过创建每分钟更新一次的 Timeline,但这并非最佳方案。正如官方文档所说,系统更新 Timeline 的频率并非完全按照开发者设定的时间间隔,而是会根据自身的资源预算进行调整。那么,如何在不影响 Widget 性能的情况下,实现我们想要的日期格式呢?

答案比你想象的更简单。我们无需频繁更新 Timeline,也不需要借助其他复杂的第三方库,SwiftUI 内置的 DateFormatter 就能轻松解决这个问题。

DateFormatter:格式化日期的利器

DateFormatter 是 Foundation 框架中用于格式化日期的强大工具。通过设置 dateStyletimeStyle 属性,我们可以灵活地控制日期和时间的显示格式,从而满足各种需求。

让我们来看看如何在 Widget 中使用 DateFormatter 将时间显示为「下午 2:30」格式:

  1. 创建 DateFormatter 实例

    let dateFormatter = DateFormatter()
    
  2. 设置日期和时间样式

    dateFormatter.dateStyle = .none // 隐藏日期显示
    dateFormatter.timeStyle = .short // 使用简短的时间样式,例如「2:30 PM」
    
  3. 使用 DateFormatter 格式化日期

    let formattedTime = dateFormatter.string(from: entry.date)
    
  4. 在 Widget 中显示格式化后的时间

    var body: some View {
        VStack {
            Text(formattedTime) // 显示「下午 2:30」格式的时间
        } 
    }
    

通过以上简单四步,你的 Widget 就能以用户友好的「下午 2:30」格式显示时间了。

完整代码示例

为了让你更直观地了解如何实现,这里提供一个完整的代码示例:

import SwiftUI
import WidgetKit

struct SimpleEntry: TimelineEntry {
    let date: Date
}

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date())
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date())
        completion(entry)
    }

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

struct YourWidgetEntryView : View {
    var entry: Provider.Entry

    let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateStyle = .none
        formatter.timeStyle = .short
        return formatter
    }()

    var body: some View {
        VStack {
            Text(dateFormatter.string(from: entry.date))
        }
    }
}

常见问题解答

  1. DateFormatter 还能实现哪些时间格式?

    DateFormatter 支持多种日期和时间格式,你可以根据需要设置 dateStyletimeStyle 属性,例如:

    • dateFormatter.dateFormat = "yyyy-MM-dd":显示「2023-10-27」格式的日期
    • dateFormatter.dateFormat = "HH:mm:ss":显示「14:30:25」格式的 24 小时制时间
  2. 如何让 Widget 每分钟更新一次时间?

    虽然不建议频繁更新 Timeline,但如果你的 Widget 必须实时显示时间,可以将 Timeline 的 policy 设置为 .atEnd,并在 getTimeline 方法中创建一个包含未来一分钟内所有时间点的数组。

  3. 除了 dateStyletimeStyle,DateFormatter 还有哪些属性可以设置?

    DateFormatter 还提供了许多其他属性,例如 localetimeZonecalendar,可以用于设置语言、时区和日历等。

  4. 如何在 Widget 中显示其他语言的时间格式?

    你可以通过设置 DateFormatterlocale 属性来实现。例如,要显示法语的时间格式,可以使用以下代码:

    dateFormatter.locale = Locale(identifier: "fr_FR")
    
  5. 如何自定义时间格式,例如显示「下午两点半」?

    你可以使用 dateFormat 属性来自定义时间格式。例如,要显示「下午两点半」,可以使用以下代码:

    dateFormatter.dateFormat = "a h:mm"
    

结语

通过巧妙运用 DateFormatter,我们无需频繁更新 Timeline 即可轻松实现 SwiftUI Widget 中时间格式的自由定制。希望这篇文章能够帮助你解决实际问题,并在 SwiftUI Widget 开发的道路上更进一步。