Apple Clockkit - 同一家庭的多种并发症

Apple Clockkit - Multiple complications for same family

作为创建复杂功能的起点,可以通过实施如下所示的复杂功能委托示例代码以下列方式呈现静态数据:

此结构意味着我只能为每个复杂功能系列创建一个复杂功能。这是真的?我还有其他选择吗?

例如,除了下面的那个之外,我将如何创建另一个不同类型的模块化小型复杂功能,即。 CLKComplicationTemplateModularSmallStackImage 以便两者都显示在模块化小区域中?

这可能是可以管理的用户偏好吗?

#pragma mark - Placeholder Templates

- (void)getPlaceholderTemplateForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTemplate * __nullable complicationTemplate))handler {
// This method will be called once per supported complication, and the results will be cached


if  (complication.family == CLKComplicationFamilyModularSmall){

    CLKComplicationTemplateModularSmallStackText *template = [[CLKComplicationTemplateModularSmallStackText alloc] init];
    //     template.headerTextProvider = [CLKSimpleTextProvider textProviderWithText:@"Title Text"];
    template.line1TextProvider = [CLKSimpleTextProvider textProviderWithText:@"TEXT1"];
    template.line2TextProvider = [CLKSimpleTextProvider textProviderWithText:@"TEXT2"];
    template.tintColor = [UIColor whiteColor];

    handler(template);


} else if (complication.family == CLKComplicationFamilyModularLarge){


    CLKComplicationTemplateModularLargeStandardBody *template = [[CLKComplicationTemplateModularLargeStandardBody alloc] init];
    template.headerTextProvider = [CLKSimpleTextProvider textProviderWithText:@"Text1"];
    template.body1TextProvider = [CLKSimpleTextProvider textProviderWithText:@"Text2"];
    template.body2TextProvider = [CLKSimpleTextProvider textProviderWithText:@"Text3"];


    UIImage *surfMain = [UIImage imageNamed:@"person"];

    template.headerImageProvider = [CLKImageProvider imageProviderWithOnePieceImage:surfMain];



    handler(template);
}

}

目前,您无法为特定家庭提供多种选择。您应该在为该家庭提供的模板中选择最佳模板。

对于您的特定示例,有七个不同的模块化小模板。即使您仅限于为用户提供两种选择,如果每个支持复杂功能的应用程序都将其在特定家庭中提供的选择数量增加一倍或三倍,那么扩展性也不会很好。

  • 用户体验视角:

    它避免了破坏性的用户体验,从必须在滚动应用程序到滚动应用程序的多个选择之间转换,只是为了让用户跳过你的选择,转到他们想要的不同应用程序的复杂功能 select.

  • 开发者视角:

    如果用户可以选择同时显示您应用程序的两个或三个不同的模块化小复杂功能,复杂功能服务器将不得不多次调用您的特定数据源,只是为了让您的每个活跃的复杂功能保持最新状态日期。有每日预算需要考虑,更不用说我们的扩展变得有点难以阅读和维护,如果我们不得不打开家庭,然后通过特定的模板。

Apple 似乎为用户和开发人员选择了一个好的设计,将其限制为每个家庭只有一个复杂功能。如果你有理由支持不止一个,你可以submit a feature request到Apple Watch团队。

之前的回答已经过时了。 WatchOS 7 及更高版本,我们现在可以为我们的应用向同一个复杂功能系列添加多个复杂功能。

第 1 步:

在我们的 ComplicationController.swift 文件中,我们可以使用 getComplicationDescriptors 函数,它允许我们描述我们在应用程序中提供的复杂功能。

descriptors 数组中,我们可以为我们想要构建的每个系列的每种复杂功能追加一个 CLKComplicationDescriptor()

func getComplicationDescriptors(
  handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
  var descriptors: [CLKComplicationDescriptor] = []
  for progressType in dataController.getProgressTypes() {
    var dataDict = Dictionary<AnyHashable, Any>()
    dataDict = ["id": progressType.id]
    
    // userInfo helps us know which type of complication was interacted with by the user
    let userActivity = NSUserActivity(
       activityType: "org.example.foo")
    userActivity.userInfo = dataDict

    descriptors.append(
       CLKComplicationDescriptor(
         identifier: "\(progressType.id)", 
         displayName: "\(progressType.title)",
         supportedFamilies: CLKComplicationFamily.allCases, // you can replace CLKComplicationFamily.allCases with an array of complication families you wish to support
         userActivity: userActivity)
    )
  }
  handler(descriptors)
}

该应用程序现在将为您支持的每个复杂功能系列提供多个复杂功能(等于 dataController.getProgressTypes() 数组的长度)。

但是现在如何针对不同的并发症显示不同的数据和视图?

第 2 步:

getCurrentTimelineEntriesgetTimelineEntries 函数中,我们可以使用 complication.identifier 值来识别调用此复杂项时传递的数据。

例如,在 getTimelineEntries 函数中:

 func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
    // Call the handler with the timeline entries after the given date
    var entries: [CLKComplicationTimelineEntry] = []
    
    ...
    ...
    ...
    
    var next: ProgressDetails
    // Find the progressType to show using the complication identifier
    if let progressType = dataController.getProgressAt(date: current).first(where: {[=11=].id == complication.identifier}) {
      next = progressType
    } else {
      next = dataController.getProgressAt(date: current)[0] // Default to the first progressType
    }
     
    let template = makeTemplate(for: next, complication: complication)
    let entry = CLKComplicationTimelineEntry(
        date: current,
        complicationTemplate: template)
    entries.append(entry)

    ...
    ...
    ...

    handler(entries)
  }

您可以类似地找到在 getCurrentTimelineEntrygetLocalizableSampleTemplate 函数中传递的数据。

第 3 步:

尽情享受吧!