WatchOS2.0 自定义表盘元素

时间:2022-03-16 13:50:32

WatchOS2.0 自定义表盘元素

北京时间6月9日凌晨1点,苹果在美国旧金山举行了WWDC2015全球开发者大会发布新的WatchOS2.0操作系统,不仅与之前WatchOS1系统结构的改变,还添加许多新的功能、新特性及新UI控件,其中WatchOS2.0新Complications(自定义表盘元素)我认为是WatchOS2.0的亮点,好那么我们下面就来聊一聊这东西。

首先在WatchOS1的时候,只支持简单自定义配置表盘。watchOS2支持自定义表盘的Complication(苹果把表盘上显示的每一个控件称之为Complication)。苹果已经做使定制Complication在watchOS2的非常好的工作。WatchoOS现在包含ClockKit(表盘开发工具包),他包含了所有可定制化的Complication类型。自定义表盘的工作方式是非常简单的,只需要你的Watch Extension提供实现CLKComplicationDataSource协议,提供给ClockKit(表盘)数据。

创建一个自定义表盘元素项目

创建一个自定义表盘元素(Complication)项目,只需要你在创建项目时候勾选”Include Complication”。

WatchOS2.0 自定义表盘元素

勾选”Include Complication”之后你的工程添加“ComplicationController”类,它用来配置你的Complication。当你在xcode查看你的Watch Extension的target,你将会看到配置你支持Complication的五大家族

WatchOS2.0 自定义表盘元素

Complication家族

Complication分为五个不同的家族。下面我们来看以下五大家族分类。

Modular large 和 Modular small

WatchOS2.0 自定义表盘元素

当前显示的是Standard Body Template.它可以显示多行数据,第一行时它的标题行,下面称为“body 1” 和 “body 2”.

let tmpl = CLKComplicationTemplateModularLargeStandardBody()
tmpl.headerTextProvider = CLKTimeIntervalTextProvider(startDate: NSDate(), endDate: NSDate().dateByAddingTimeInterval(MatchDurtion))
tmpl.body1TextProvider = CLKSimpleTextProvider(text: "Lunch with Paul")
tmpl.body2TextProvider = CLKSimpleTextProvider(text: "Zero Zero")

WatchOS2.0 自定义表盘元素

模块化(Modular)的表盘里面有一个块大的部分和四块小的部分,大的部分称为Modular large,小的部分称为Modular small,可以通过滚动Digital Crown来选择不同的Complication(表盘控件)。

Utilitarian large 和 Utilitarian small

WatchOS2.0 自定义表盘元素
WatchOS2.0 自定义表盘元素

实用型(Utilitarian)的表盘里面有底部一块大的部分和顶部两块小的部分,大的部分称为Utilitarian large,小的部分称为Utilitarian small类型。

Circular small

WatchOS2.0 自定义表盘元素

节约(Circular)的表盘里面包含四块小的部分称为Circular small。

Complication 布局

提供给表盘(ClockKit)显示元素主要是通过CKComplicationTemplate,每一种家族的表盘元素 (complication)都有特定的子类,目前为止测速版,它一共提供用23个子类。
如下:

WatchOS2.0 自定义表盘元素

通过自己的业务需求来选择数据展示所需模版。

Templates and Providers

通过上面学习我们知道,我们可以通过选择模版来展示我们的数据。那么我们的数据如何显示在模版上的呢?我们可以通过设置模版的Providers(提供者),Providers是非常灵活的,提供了各种各样的Provider,如需要显示文本内容,我们有CLKTextProvider,它的子类CLKSimpleTextProvider非常常用,它有个text属性,设置这个属性提供给模版显示简单的文本内容。显示图片用CLKImageProvider提供给模版显示简单图片。使用CLKDateTextProvider,CLKTimeTextProvider和relativCLKRelativeDateTextProvider来为表盘显示时间。

//1.创建选择的模版
let tmpl = CLKComplicationTemplateModularLargeStandardBody()
//2.使用Provider设置要显示的数据
tmpl.headerImageProvider = CLKImageProvider(onePieceImage:UIImage(named: "soccer_ball")!)
tmpl.headerTextProvider = CLKTimeTextProvider(date: match.date!)
tmpl.body1TextProvider = CLKSimpleTextProvider(text: match.teamDesc!)
tmpl.body2TextProvider = CLKSimpleTextProvider(text: match.groupDesc!)

如何工作?

当你安装了一个带有Complication的应用,它的extension会自动启动。这个getPlaceholderTemplateForComplication:withHandler: 方法会首先被调用一次为每个支持的Complication,值会被缓存整改应用的生命周期。这个主要是placeholder模型给用户。
一旦placeholder被使用,用户将安装你的Complication,如果已经安装,你的extension将会被唤醒调用getCurrentTimelineEntryForComplication:withHandler: 它需要一个现在complication显示结果。在次之后,系统将自动调用getNextRequestedUpdateDateWithHandler:去请求下一次数据刷新。最后通过-getPrivacyBehaviorForComplication:withHandler: 让watch知道,在锁屏时候是否隐藏Complication。

Time Travel: 显示过去/未来事件

当用户在转动Digital Crownhs时,watch将进入Time Travel模式,下面一些方法来支持Time Travel。
* getSupportedTimeTravelDirectionsForComplication:withHandler:
* getTimelineStartDateForComplication:withHandler:
* getTimelineEndDateForComplication:withHandler:
* getTimelineEntriesForComplication:beforeDate:limit:withHandler:
* getTimelineEntriesForComplication:afterDate:limit:withHandler:

这些方法都是为Time Travel工作,entries是CLKComplicationTimelineEntry对象,它包括NSDate和CLKComplicationTemplate。

这是关于事件有趣的事情,来举例说明:比如说今天有三场足球比赛,第一场10点半、第二场13点半、第三场17点半。那么我们要在complication上提醒用户现在或将要进行的那场球赛,那么首先我们要提供整个时间线的开始、结束时间通过getTimelineStartDateForComplication:withHandler:和getTimelineEndDateForComplication:withHandler:。

   func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
//timeline开始时间
let startDate = SoccerMatch.firstMatch()?.date?.dateByAddingTimeInterval(-60 * 10)
handler(startDate)
}
    func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
//timeline结束时间
let endDate = SoccerMatch.lastMatch()?.date?.dateByAddingTimeInterval(MatchDurtion)
handler(endDate)

}

如何根据Time Travel的时间来显示该时间将要或进行中的比赛呢?那么我们就可以通过getTimelineEntriesForComplication:beforeDate:limit:withHandler:和 getTimelineEntriesForComplication:afterDate:limit:withHandler:来根据条件来取得当前比赛。

    func getTimelineEntriesForComplication(complication: CLKComplication, beforeDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {
// Call the handler with the timeline entries prior to the given date
//构造返回的enties
var enties = [CLKComplicationTimelineEntry]()

var match = SoccerMatch.lastMatch()
//去比赛数据中匹配 如果满足条件 添加到 enties

while let thisMatch = match {
//获取进入这场比赛的Entry时间
let thisMatchEntryDate = entryDateForMatch(thisMatch)
print(enties)
print(match)
if date.compare(thisMatchEntryDate!) == .OrderedDescending
{
let timelineEntry = CLKComplicationTimelineEntry()
timelineEntry.complicationTemplate = templateForMatch(match!)
timelineEntry.date = thisMatchEntryDate!
enties.append(timelineEntry)

if enties.count==limit {break}
}
match = match?.frontMatch()

}
// Call the handler with the timeline entries after to the given date
handler(enties)
}
    func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) {
//构造返回的enties
var enties = [CLKComplicationTimelineEntry]()

var match = SoccerMatch.firstMatch()
//去比赛数据中匹配 如果满足条件 添加到 enties

while let thisMatch = match {
//获取进入这场比赛的Entry时间
let thisMatchEntryDate = entryDateForMatch(thisMatch)
print(enties)
print(match)
if date.compare(thisMatchEntryDate!) == .OrderedAscending
{
let timelineEntry = CLKComplicationTimelineEntry()
timelineEntry.complicationTemplate = templateForMatch(match!)
timelineEntry.date = thisMatchEntryDate!
enties.append(timelineEntry)

if enties.count==limit {break}
}
match = match?.nextMatch()

}


// Call the handler with the timeline entries after to the given date
handler(enties)
}

刷新数据

当你的应用底层数据改变时候, 你想要刷新complications去更新新数据.你可以通过以下代码:

 func refreshComplications() {
let server = CLKComplicationServer.sharedInstance()
for complication in server.activeComplications
{
//刷新complication数据
server.reloadTimelineForComplication(complication)
}
}

那么关于自定义表盘元素就介绍到这里,希望对你有所帮助。

禁止转载!!!