如何在 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" 直到所有的并发症数据再次生成。
我只能想到几个解决这个问题的方法,它们都有缺点:
我可以计算日期还有多少天,然后在适当的时候给 CLKSimpleTextProvider
字符串 "Today" 或 "Tomorrow"。我主要担心的是我在我的应用程序的其他地方使用了 NSDateFormatter
,我希望与它保持一致。用各种语言来解释这不是微不足道的。仅举一个简单的例子,法语使用 "après-demain",意思是 "the day after tomorrow",在英语中没有对应的
我可以给 NSDateFormatter
错误的日期,迫使它给我我想要的输出。假设并发症发生日期是 6 月 14 日,而目前是 6 月 13 日。当我的应用程序为当天创建时间线条目时,它会使用日期 6 月 14 日 ("Tomorrow") 调用我的日期格式化程序。但是当它需要在午夜之后创建时间线数据时,它会调用日期格式化程序,日期为 6 月 13 日 ("Today")。这似乎是一个糟糕的想法,在闰年或时间变化等情况下必然会失败。我已经不喜欢使用 CLKRelativeDateTextProvider
以外的任何东西,但我 真的 不喜欢这个。
也就是说,我不确定我还能做什么。我已经提交了一份 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" 两个。
感觉这是一个非常不令人满意的选择,因为您现在要承担管理每种语言和描述未来日子的每种可能方式的责任,但它可以工作。
我有一个 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" 直到所有的并发症数据再次生成。
我只能想到几个解决这个问题的方法,它们都有缺点:
我可以计算日期还有多少天,然后在适当的时候给
CLKSimpleTextProvider
字符串 "Today" 或 "Tomorrow"。我主要担心的是我在我的应用程序的其他地方使用了NSDateFormatter
,我希望与它保持一致。用各种语言来解释这不是微不足道的。仅举一个简单的例子,法语使用 "après-demain",意思是 "the day after tomorrow",在英语中没有对应的我可以给
NSDateFormatter
错误的日期,迫使它给我我想要的输出。假设并发症发生日期是 6 月 14 日,而目前是 6 月 13 日。当我的应用程序为当天创建时间线条目时,它会使用日期 6 月 14 日 ("Tomorrow") 调用我的日期格式化程序。但是当它需要在午夜之后创建时间线数据时,它会调用日期格式化程序,日期为 6 月 13 日 ("Today")。这似乎是一个糟糕的想法,在闰年或时间变化等情况下必然会失败。我已经不喜欢使用CLKRelativeDateTextProvider
以外的任何东西,但我 真的 不喜欢这个。
也就是说,我不确定我还能做什么。我已经提交了一份 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" 两个。
感觉这是一个非常不令人满意的选择,因为您现在要承担管理每种语言和描述未来日子的每种可能方式的责任,但它可以工作。