swift Apple Watch App 如何添加 Complication

swift Apple Watch App 如何添加 Complication

建议每个 Apple Watch 应用都实现 ComplicationComplication 就是能显示在表盘上的一些应用组件,实现 Complication 之后系统会给予一些优先的权限,比如后台任务刷新:在没有实现 Complication 的时候系统1小时只会分配一次后台刷新,实现之后会实现多次。

添加 Complication 的官方说明: https://developer.apple.com/documentation/clockkit/adding_a_complication_to_your_watchos_app

当你在新建项目的时候没有勾选 complication 这一项,在后来又如何添加呢?

1. 新建一个实现了 CLKComplicationDataSource 的类

点击 fix 系统会自动添加这个 protocal 中必需的方法和变量。

datasource-2.png

2. 配置 complication

点击总项目,选择 targetextension, 如图
select-extenstion-target.png

再切到 general 标签,就会看到对应的 complication 的相关设置了
complication-setting.png

3. 实现代码

显示在表盘的 complication 需要通过实现 CLKComplicationDataSource 接口的类获取它需要的数据。

必须实现 CLKComplicationDataSource 中的两个方法,
一个是用于定义 complication 可获取的数据方向 getSupportedTimeTravelDirections
一个是给 complication 实时显示提供数据

注意: 因为 complication 显示是实时的,所以不要在提供数据的方法里写过量计算、需要大量时间运行的代码,如果需要显示一些大量计算的数据,一定要事先把数据处理好并存在一个地方,在用的时候直接取就可以了,不耗费时间。

还有其它一些可选的方法,具体可以查看 --> CLKComplicationDataSource 的 API <--
如,

// 提供时间轴中未来数据样本的方法:
func getTimelineEntries(for complication: CLKComplication, before date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void)
// 提供时间轴中过去数据样本的方法:
func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void)

4. 具体实现代码

比如我的

1) 定义 complication 可向 [前,后] 两个方向获取数据

func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.forward, .backward])
}

2) 给实时显示在表盘的 complication 提供显示的数据

这里需要说明一下:
a. 关于表盘插件的样式
所有可能表盘插件样式都在 CLKComplicationFamily 里列出来了,可以查看 CLKComplicationFamily 官方文档了解

b. 关于实现表盘数据的类
所有 template 样板都是从虚拟类 CLKComplicationTemplate 继承过来的,包括各种表盘插件所用的样式类,根据自己需要进行操作,如下图,都是:

CLKComplicationTemplate.png

func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
    var startLevel = 0
    var timeDistance = 0.0
    if let timeStart = defaults.object(forKey: Const.timeStart) as? Date {
        startLevel = Int(defaults.double(forKey: Const.startLevel) * 100)
        timeDistance = Date().distance(to: timeStart)
    }
    switch complication.family {
    
    // 这里,对应不同的 family,也就是表盘中的插件样式的不同,需要返回对应样式的 template。
    case .graphicCircular:
        let template = CLKComplicationTemplateGraphicCircularStackText()
        template.line1TextProvider = CLKSimpleTextProvider(text: "\(startLevel)")
        template.line2TextProvider = CLKSimpleTextProvider(text: timeDistance.timeFormatString)
        let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
        handler(entry)
    case .graphicCorner:
        // 不同 template 有不同的实现类
        let template = CLKComplicationTemplateGraphicCornerStackText()
        template.innerTextProvider = CLKSimpleTextProvider(text: "\(startLevel)")
        template.outerTextProvider = CLKSimpleTextProvider(text: timeDistance.timeFormatString)
        let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
        handler(entry)
    case .graphicBezel:
        let circle = CLKComplicationTemplateGraphicCircular()
        circle.tintColor = Colors.magenta
        let template = CLKComplicationTemplateGraphicBezelCircularText()
        template.circularTemplate = circle
        template.textProvider = CLKSimpleTextProvider(text: timeDistance.timeFormatString)
        let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
        handler(entry)
    default:
        handler(nil)
    }
}

5. 结果

获取应用中的两个数据,传递到表盘插件中

clock-face.JPG

你可能感兴趣的:(swift,watchos,ios,apple,xcode)