如何在 watchOS 复杂功能中使用 "Today" 或 "Tomorrow" 等相对日期?

How can I use relative dates like "Today" or "Tomorrow" in a watchOS complication?

我有一个 watchOS 复杂功能,可以显示有关当天或未来某天发生的事情的信息。与任何并发症一样,我使用各种方法设置了 CLKComplicationDataSource,包括 getCurrentTimelineEntryForComplication:withHandler:getTimelineEntriesForComplication:afterDate:limit:withHandler:。调用这些方法时,我使用适合并发症类型的 CLKComplicationTemplate 子类创建 CLKComplicationTimelineEntry

"Modular Large" 并发症类型 (CLKComplicationFamilyModularLarge) 是给我带来最多麻烦的一种。对于这种类型,我希望标题在适当的时候显示 "Today" 或 "Tomorrow"。下面将是一些关于当天发生的事情的文字。目前我为此使用 CLKRelativeDateTextProvider

template.headerTextProvider = [CLKRelativeDateTextProvider textProviderWithDate:date style:CLKRelativeDateStyleNatural units:NSCalendarUnitDay];

虽然这并没有完全满足我的要求——它显示了类似“0DAYS”或“1DAY”的内容。这对于较小的并发症来说是可以接受的,但对于 Modular Large 来说,它看起来特别尴尬。无论有多少额外空间,您甚至都不会在数字后得到 space。

我想我可以通过使用 NSDateFormatter 生成字符串,然后使用 CLKSimpleTextProvider 来显示它来解决这个问题。看起来很简单:

NSDateFormatter *formatter = [NSDateFormatter new];
formatter.doesRelativeDateFormatting = YES;
formatter.dateStyle = NSDateFormatterShortStyle;
formatter.timeStyle = NSDateFormatterNoStyle;
NSString *string = [formatter stringFromDate:date];

但有一个问题:watchOS 复杂功能需要能够提供未来日期的数据。据我所知,NSDateFormatter 无法告诉它您希望输出相对于哪个日期——它始终相对于当前日期。因此,如果并发症数据的日期是明天,并且调用了 getTimelineEntriesForComplication:afterDate:limit:withHandler:,那么我生成的所有时间线条目都会显示 "Tomorrow"。这对当天是正确的,但当午夜到来时,它就会出错。它仍然会说 "Tomorrow" 直到所有的并发症数据再次生成。

我只能想到几个解决这个问题的方法,它们都有缺点:

也就是说,我不确定我还能做什么。我已经提交了一份 Radar (27267550: CLKRelativeDateTextProvider should offer more control),要求提供更多日期格式选项。它已经一年了,没有迹象表明 watchOS 4 会解决这个问题。

解决这个问题的最佳方法是什么?

我认为 NSDateFormatter 是最好的选择。如果您尝试安排在午夜刷新时间线,那么您应该能够避免日期超过当天的问题。无法保证穿越国际日期变更线的人! :)

如果您采用计算还有多少天的方法,则可以使用 localized .stringsdict 并根据数字获取本地化字符串。对于英语,它可以是:

<key>zero</key>
<string>Today</string>
<key>one</key>
<string>Tomorrow</string>
...
<key>other</key>
<string>%d days</string>

然后对于其他语言,您可以添加特定规则,例如法语的 "après-demain" 两个。

感觉这是一个非常不令人满意的选择,因为您现在要承担管理每种语言和描述未来日子的每种可能方式的责任,但它可以工作。