暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

apple watch 编程指南

yBmZlQzJ 2024-01-17
639

图片

.1

Apple Watch

编程指南

前言

本教程翻译自

Apple

官方发行的

Apple Watch Programming Guide

编程指南,为开发者提供权威的编程指导。

本教程关于使用

API

以及相关技术的初步文档,苹果提供此文档便于你在苹果的相关产品上开发应用软件。后期该文档会有所变动,所以依据本文档开发的应用软件应当使用最新的

操作系统进行测试,该文档的新版本会进一步提供

API

以及相关技术支持。

1

概述

开发您的

Watch

应用

>

重要提示

这是一篇关于使用

API

以及相关技术的初步文档,苹果提供此文档便于你在苹果的相关产品上开发应用软件。后期该文档会有所变动,所以依据本文档开发的应用软件应当使用最新

的操作系统进行测试,该文档的新版本会进一步提供

API

以及相关技术支持。

Apple Watch

给用户呈现了一种人性化,极为容易的获取信息的方式。相较于从口袋里掏出

iPhone

而言,直接看一眼

Apple Watch

来查看信息更加便利。所以,给

Apple Watch

编写的

应用程序需要具备极为简易的交互流程,尽可能简单而直白的操作方式。

图片

1.1

image

Apple Watch

的运行需要配合

iPhone

运行对应的第三方应用。创建第三方应用需要两个不同的可执行文件:在

Apple Watch

上运行的

Watch

应用,以及在用户

iPhone

上运行的

WatchKit

应用扩展。

Watch

应用只包含与应用程序的用户界面相关的

storyboards

以及资源文件。

WatchKit

应用扩展则包含了用于管理、监听应用程序的用户界面以及响应用户交互的代码。借助

这两个可执行程序,您可以在

Apple Watch

上运行不同类型的用户界面:

Watch

应用拥有

iOS

应用的完整用户界面。用户从主界面启动手表应用,来查看或处理信息。

使用

glance

界面以便在

Watch

应用上显示即时、相关的信息,该界面是可选的只读界面。并不是所有的

Watch

应用都需要使用

glance

界面。

自定义通知界面可以让您修改默认的本地或远程通知界面,并可以添加自定义控件,内容以及设置风格。自定义通知界面是可选的。

Watch

应用需要尽可能实现

Apple Watch

提供的所有交互动作。由于

Watch

应用目的在于扩展

iOS

应用的功能,因此

Watch

应用和

WatchKit

应用扩展将被捆绑在一起,并且都会被打包

iOS

应用包当中。如果用户有与

iOS

设备配对了

Apple Watch

,那么随着

iOS

应用的安装,系统将会提示用户安装相应的

Watch

应用。

Watch

应用

Watch

应用是在

Apple Watch

上交互的主体。

Watch

应用通常是从

Apple Watch

的主屏幕上访问,并且能够提供一部分关联

iOS

应用的功能。

Watch

应用的目的在于让用户快速浏览相关

数据。

Watch

应用与

iPhone

上运行的

WatchKit

应用(扩展)协同工作,它不包含任何自定义代码,仅仅只是存储了故事板以及和用户界面相关联的资源文件。

WatchKit

应用扩展是实现这些操作的核心所在。它包含了页面逻辑以及用来管理内容的代码,实现用户操作响应,并且刷新用户界面。由于应用扩展是在用户的

iPhone

上运行,因此

它能轻易地和

iOS

应用协同工作,比如说收集坐标位置或者执行其他长期运行任务。

要开始创建

Watch

应用,请参考:

App Essential

创建

Glance

界面

Glance

是一个展示即时重要信息的界面。

glance

中的内容应当言简意赅,因为其目的是让用户迅速地查看消息。

Glance

不支持滚动,因此整个

glance

界面只能在单个界面上显示,您

需要保证它拥有合适的大小。

glance

只读,因此不能包含按钮、开关,或者其它交互动作。点击

glance

则会直接启动您的

Watch

应用。

您需要在

WatchKit

应用扩展中添加管理

glance

的代码,用来管理

glance

界面的类与

Watch

应用的类相同。即便如此,创建

glance

更容易实现,因为其无需响应用户交互动作。

要开始创建

glance

界面,请参阅:

Glance Essentials

自定义通知界面

Apple Watch

能够和与之配对的

iPhone

协同工作,来显示本地或者远程通知。

Apple Watch

首先使用一个小窗口来显示通知信息。当用户移动手腕希望看到更多的信息时,这个小窗口

便会显示更详细的通知内容。应用可以提供详情界面的自定义版本,并且可以添加自定义控件或者改变系统默认的通知信息。

Apple Watch

支持

iOS 8

中引入的交互式通知。交互式通知通过在通知上添加按钮来让用户立即做出回应。比如说,一个日历时间通知可能会包含了接收或拒绝某个会议邀请的按钮。

只要你的

iOS

应用支持交互式通知,那么

Apple Watch

就会自行向自定义或默认通知界面上添加合适的按钮。你所需要做的只是在

WatchKit

应用扩展中处理这些事件而已。

要开始创建自定义通知界面,请参阅:

Notification Essentials

配置

Xcode

项目

Xcode

会将

Watch

应用和

WatchKit

应用扩展一起打包,然后放进现有的

iOS

应用包中。

Xcode

提供了一个搭建

Watch

应用的模板,其中包含了创建应用、

glance

,以及自定义通知界面

所需的所有资源。你可以在项目中进行实时测试。

Xcode

中的

WatchKit

应用包已经包含了所有你需要的资源来创建出

WatchKit

应用。包括

glances

,自定义通知界面。并且

iOS

模拟器提供了一个实时环境来测试它的界面以及所有的接

口。

>

重要提示

WatchKit

开发环境需要

iOS 8.2

以上的

SDK

,请在

developer.apple.com

获取最新

SDK

iOS

应用中添加

Watch

应用

要向现有项目中添加

Watch

应用对象,请执行以下操作:

1.

打开现有的

iOS

应用项目

2.

选择

File > New > Target

,然后选中

Apple Watch

3.

选择

Watch App

,然后单击

Next

4.

如果您想要使用

glance

或者自定义通知界面,请选择相应的选项我们建议您激活应用通知选项。选中之后就会创建一个新的文件来调试该通知界面。如果您没有选择这个选项,

那么之后您只能手动创建这个文件了。

5.

单击

Finish

完成上述操作之后,

Xcode

WatchKit

应用扩展所需的文件以及

Watch

应用添加到项目当中,并自动配置相应的设置。

Xcode

将基于

iOS

应用的

bundle ID

来为两个新对象设置它们的

bundle ID

。比如说,

iOS

应用的

bundle ID

com.example.MyApp

,那么

Watch

应用的

bundle ID

将被设置为

com.example.MyApp.watchapp

WatchKit

应用扩展的

bundle ID

被设置为

com.example.MyApp.watchkitextension

。这三个可执行对象的基本

ID

(即

com.example.MyApp

)必须相匹配,如果您更改了

iOS

应用的

bundle ID

,那么您就必须相应的更改另外

两个对象的

bundle ID

应用软件结构

Xcode

中的

WatchKit

应用扩展模板为

iOS

应用创建了两个新的可执行程序。

Xcode

同时也配置了项目的编译依赖,从而让

Xcode

在编译

iOS

应用的同时也编译这两个可执行文件。

2-1

说明了它们的依赖关系,并解释了

Xcode

是如何将它们打包在一起的。

WatchKit

依赖于

iOS

应用,而其同时又被

Watch

应用依赖。编译

iOS

应用将会将这三个对象同时编译并

打包。

2-1

Watch

应用对象的结构

图片

1.2

Watch

应用对象的结构

编译、运行以及调试程序

当您创建完

Watch

应用对象后,

Xcode

将自行配置用于运行和调试应用的编译方案。使用该配置在

iOS

模拟器或真机上启动并运行您的应用。

对于包含

glance

或者自定义通知的应用来说,

Xcode

会分别为其配置不同的编译方案。使用

glance

配置以在模拟器中调试

glance

界面,使用通知配置以测试静态和动态界面。

glance

和通知配置自定义编译方案

1

、选择现有的

Watch

应用方案

2

、从方案菜单中选择

Edit Scheme

图片

1.3

image

3

、复制现有的

Watch

应用方案,然后给新方案取一个合适的名字。

比如说,命名为

“Glance - My Watch app”

,表示该方案是专门用来运行和调试

glance

4

、选择方案编辑器左侧栏的

Run

选项

5

、在信息选项卡中,选择合适的可执行对象

图片

1.4

image

6

、关闭方案编辑器以保存更改

指定一个通知进行测试

当您在

iOS

模拟器调试自定义通知界面的时候,您可以指定一个

JSON

负载来模拟推送的通知。通知界面的

Xcode

模板包含一个

RemoteNotificationPayload.json

文件,您可以用它来指

定负载中的数据。这个文件位于

WatchKit

应用扩展的

Supporting Files

文件夹。只有当您在创建

Watch

应用时勾选了通知场景选项,这个文件才会被创建。如果这个文件不存在,您可

以用一个新的空文件手动创建它。

RemoteNotificationPayload.json

文件包含了绝大多数您需要的键值,但是您可以根据应用程序的实际情况添加更多的键值。图

2-2

展示了项目中的默认

JSON

文件。由于

iOS

拟器无法访问

iOS

应用的注册动作,这个负载便包含了一个名为

“WatchKit Simulator Actions”

的键值,其值为一个包含了一系列动作的数组。每个动作按钮含有

title

identifier

键,它们的值和

iOS

应用中注册的相应键值相同。

2-2

一个模拟的远程通知负载

图片

1.5

一个模拟的远程通知负载

绝大部分的

JSON

数据会在运行时打包进字典中进行传输。因为

iOS

模拟器没办法处理

iOS

应用的预置动作。您也许需要负载文件来指定您的动作。

WatchKit

模拟器包含了一个行为

的数组。数组中的每一个元素包含了以下内容:

标题

-

行为的标题,必须包含这个键值

id

标示

-

用来传递你的视图控制器的

application:handleActionWithIdentifier:forLocalNotification:completionHandler:

或者

application:handleActionWithIdentifier:forRemoteNotification:completionHandler:

,必须包含这个键值

destructive

-

这个键值包含两个值,

1

0

1

会导致按钮被渲染成

destructive

的样式。

0

会导致按钮被渲染成普通模式,这个键值是可选的。

为了用

JSON

负载测试您的通知接口,您需要用

appropriate

负载文件来配置

build scheme

。当您选择了一个通知接口的可执行文件,

Xcode

会添加一个菜单来选择您的负载文件。您可

以用不同的

build schemes

来加载不同的配置文件,或者您也可以修改以前的负载文件来达到更新的目的。

Watch

应用结构

Apple Watch

应用程序包含两个部分:

Watch

应用和

WatchKit

应用扩展。

Watch

应用驻留在用户的

Apple Watch

中,只含有故事板和资源文件,要注意它并不包含任何代码。而

WatchKit

应用扩展驻留在用户的

iPhone

上(在关联的

iOS

应用当中),含有相应的代码和管理

Watch

应用界面的资源文件。

当用户开始与

Watch

应用交互时,

Apple Watch

将会寻找一个合适的故事板场景来显示。它根据用户是否在查看应用的

glance

界面,是否在查看通知,或者是否在浏览应用的主界面等

行为来选择相应的场景。选择完场景后,

Watch OS

将通知配对的

iPhone

启动

WatchKit

应用扩展,并加载相应对象的运行界面。所有的消息交流都在后台进行。

3-1

Watch

应用和

WatchKit

应用扩展之间的通信

图片

1.6

Watch

应用和

WatchKit

应用扩展之间的通信

场景管理:界面控制器

Watch

应用的构建模块是界面控制器,它是

WKInterfaceController

类的实例。

WatchKit

中的界面控制器用来模拟

iOS

中的视图控制器:它显示、管理屏幕上的内容,并且响应用户交

互。

如果用户直接启动您的应用,系统将从主故事板文件中加载初始界面控制器。根据用户的交互,您可以显示其他界面控制器以让用户得到需要的信息。如何显示额外的界面控制器取决

于您应用所使用的界面样式。

WatchKit

支持基于页面的风格以及基于层次的风格。这两个风格不能共存的,要了解更多信息,请参阅:

Interface Navigation

>

重要提示

Glances

和通知只会显示一个包含相关信息的界面控制器。用户与界面控制器的交互操作会展示应用的主界面。要了解如何实现

glance

,请参阅

Glance Essentials

。要了解自定义通知界

面,请参阅:

Notification Essentials

Watch

应用的生命周期

Apple Watch

上的用户交互将启动您的应用并驱动其生命周期。当用户在

Apple Watch

上运行您的应用时,用户的

iPhone

会自行启动相应的

WatchKit

应用扩展。通过一系列的信号交

换,

Watch

应用和

Watch

应用扩展将互相连接,因此消息能够在二者之间流通,直到用户停止与应用进行交互为止。此时,

iOS

将暂停应用扩展的运行。

随着启动序列的运行,

WatchKit

自动为当前界面创建相应的界面控制器。如果用户正在查看

glance

WatchKit

创建出来的界面控制器将与

glance

相连接。如果用户直接启动您的应

用,

WatchKit

将从应用的主故事板文件中加载初始界面控制器。无论哪种情况,

WatchKit

应用扩展都提供一个名为

WKInterfaceController

的子类来管理相应的界面。

界面控制器对象初始化后,您就应当为其准备显示相应的界面。图

3-2

展示了

Watch

应用的启动序列。当应用启动时,

WatchKit

框架自行创建了相应的

WKInterfaceController

对象

并调用

initWithContext:

方法。使用该方法来初始化界面控制器,然后加载所需的数据,最后设置所有界面对象的值。对主界面控制器来说,初始化方法紧接着

willActivate

方法运行,

以让您知道界面已显示在屏幕上。了解更过,请参阅

App Essentials

3-2

启动

Watch

应用

图片

1.7

启动

Watch

应用

当用户在

Apple Watch

上与应用进行交互时,

WatchKit

应用扩展将保持运行。如果用户明确退出应用或者停止与

Apple Watch

进行交互,那么

iOS

将停用当前界面控制器,并暂停应用

扩展的运行,如图

3-3

所示。与

Apple Watch

的互动是非常短暂的,因此这几个步骤都有可能在数秒之间发生。所以,界面控制器应当尽可能简单,并且不要运行长时任务。重点应当

放在读取和显示用户想要的信息上来。

>

重要提示

Glance

界面不支持触摸事件响应。点击你的

glance

界面会直接进入加载应用软件。

您的

Watch Kit

扩展包只有在用户正在触发

Watch

上的事件的时候才会响应。这意味着与您的

Watch

进行数据交互会非常的简短,所以,视图控制器需要尽可能的轻量级,且不能执行

耗时的任务。当用户退出了您的应用软件,或者是中断了与

Watch

的交互。

iOS

会检测到当前的视图控制器,然后挂起您的操作。

3-3

界面控制器的生命周期

图片

1.8

界面控制器的生命周期

应用各阶段生命周期中执行的任务

在应用生命周期的不同阶段,

iOS

将会调用

WKInterfaceController

对象的相关方法来让您做出相应的操作。表

3-1

列出了大部分您应当在界面控制器中声明的主要方法。

3-1

WKInterfaceController

的主要方法

方法

方法的用途

init

初始化你的视图控制器。

awakeWithContext:

这个方法用来准备显示界面。借助它来加载数据,以及更新标签、图像和其他在故事板场景上的界面对象。

willActivate

这个方法可以让您知道该界面是否对用户可视。借助它来更新界面对象,以及完成相应的任务,完成任务只能在界面可视时使用。

方法

方法的用途

didDeactivate

使用

didDeactivate

方法来执行所有的清理任务。例如,使用此方法来废止计时器、停止动画或者停止视频流内容的传输。您不能在这个方法中设置界面控制器对

象的值,在本方法被调用之后到

willActivate

方法再次被调用之前,任何更改界面对象的企图都是被忽略的。

在模拟器上进行测试

测试期间,您可以通过锁定与解锁您的模拟器来验证是否达到了你的预期的效果。当您在使用

Hardware > Lock

命令时,

WatchKit

会调用当前控制器的

didDeactivate

方法。当您解锁了

模拟器,

WatchKit

会执行当前控制器的

willActivate

方法。

Containing iOS

应用共享数据

如果您的

iOS

应用和

WatchKit

应用扩展都依赖于相同的数据,那么您可以使用共享程序组来存储数据。共享程序组是一个位于本地文件系统的区域,应用扩展和应用都能够访问。由

于两个程序在不同的沙箱环境中运行,它们一般情况下都不与对方共享文件和进行通信。共享程序组让共享数据成为可能。你可以使用这个空间来存储共享的数据文件或者在两个程序

间交换消息。

您可以在

iOS

应用和

WatchKit

应用扩展中的

Capabilities

选项卡中启动共享程序组。激活这项功能后,

Xcode

将会为每个对象添加授权文件(需要的话),并给那个文件添加

com.apple.security.application-groups

授权。要共享数据,这两个对象必须选择相同的共享程序组。

程序运行时,您可以通过在共享容器目录中读写文件以在两个程序间共享数据。要访问容器,请使用

NSFileManager

中的

containerURLForSecurityApplicationGroupIdentifier:

方法来接

收该目录的根路径。使用方法返回的

URL

来枚举目录内容或者在目录中为文件创建新的

URL

Containing iOS

应用进行通信

Watch

使用方法

openParentApplication:reply:

来给

iOS

发送请求并等待回复。

WatchKit

扩展包并不支持后台运行;它只会在用户直接主动触碰它时才会响应。

containing iOS

应用在设置

上有许多限制,他可以被配置成后台收集

WatchKit

扩展包的数据的模式。有些事件可能需要额外的时间来完成,例如接收用户定位的数据,这个就需要通过

iOS

来收集数据,然后传

输给

Watch

当您使用

openParentApplication:reply:

方法后,

iOS

会在后台启动或者唤醒

containing iOS

应用,然后调用方法

application:handleWatchKitExtensionRequest:reply:

。这个方法会用

提供的字典数据执行请求,然后给

WatchKit

扩展包反馈结果。

使用

iOS

技术

WatchKit

应用扩展可以使用绝大多数

iOS

技术。由于应用扩展和应用还是有一些不同,因此某些技术的使用可能会受到限制,或者不受到推荐。下面是决定是否使用特定技术的准

则:

避免使用需要用户权限的技术,比如

Core Location

WatchKit

应用扩展中使用该技术的话,可能会在您第一次请求使用时导致用户的

iPhone

上显示出一个意想不到的提示。

更糟糕的是,这个状况可能会在任何时间出现,即使用户的

iPhone

在他们的口袋里并且屏幕是锁定的。

不要使用后台执行模式的技术。

WatchKit

应用扩展只考虑在前台运行的情况,并且其只在用户和对应的

Watch

应用交互时运行。因此,支持后台运行的某些技术在

WatchKit

用扩展中并不被支持。

避免使用需要长时间运行的技术。

WatchKit

应用扩展在用户停止和对应的

Watch

应用交互后便迅速暂停。由于与

Watch

应用的交互通常是短暂的,因此应用扩展可能会在请求

的数据到达前暂停运行。

要使用

iOS

技术,其中一种解决方法是让您的

iOS

应用来使用这些技术。例如,在您的

iOS

应用中使用位置服务,而不是在

WatchKit

中使用这个技术。

iOS

应用可以收集所需的数据

然后通过共享程序组来让应用扩展稍后访问。

支持

Handoff

Watch

支持创建的

Handoff

功能。你可以用控制器

WKInterfaceController

中的

updateUserActivity:userInfo:webpageURL:

方法来创建。

glance

的控制器中,你可以定制有用的信

息,来与你的设备进行交互。当用户点击了

glance

上的应用的时候,

WatchKit

将会将数据传输到你的设备上。之后,你可以用这个发送过来的数据更新您的设备上的相关内容。

远程控制事件与

Now Playing

信息

Watch

可以用远程控制事件来管你与之配对的

iPhone

,例如播放音乐、视频。设备也会将当前正在播放的音乐(或者视频)信息传输到

Watch

上显示。一个注册过

MPRemoteCommandCenter

iOS

应用程序会自动的接受数据处理信息。你不需要在你的

WatchKit

扩展包中做些额外的操作来同步数据。

>

重要提示

为了反馈类似于喜欢、不喜欢或者标记一个内容的信息,

Watch

是使用

localizedShortTitle

,而不是

MPFeedbackCommand

中的

localizedTitle

Now Playing

glance

会自动的显示当前

iOS

应用的

Now Playing

信息。

iOS

应用程序通过

MPNowPlayingInfoCenter

来提供这些数据。当您的

app

在更新数据时,您应当去更新

nowPlayingInfo

字典的内容。

Watch

会自动的更新数据并显示出来。另外,如果此时用户点击了

Now Playing

上的标题,

Watch

会直接进入

iOS

应用对应的

Watch

应用中。

更多的关于如何实现远程控制以及

Now Playing

的内容,请查阅

Remote Control Events

2

WatchKit Apps

UI

概要

开始实现

App

的第一步是定义

Storyboard

中的

Scene

。每个

Scene

定义了整个

App

用户界面的一部分。你可以为不同大小的

Apple Watch

定义不同的

Scene

,也可以为同一个界面配置

不同的展示效果。

布局

Scenes

WatchKit App

使用的布局模型不同于

iOS App

。在

Scene

里面布局

WatchKit App

界面的时候,并没有因为控件的添加而创建多层次的视图层。

Xcode

会决定你所添加到

Scene

中的控件

元素所在的位置,把他们竖直堆叠在不同的行。运行时,

Apple Watch

会取出相应的控件把它们布局在合适的区域并显示出来。

尽管

Xcode

几乎处理了所有的界面布局工作,

Watchkit

也提供了一些让你在

Scene

里面精确控制控件元素的方式。大多数控件的大小和位置可以通过属性面板来设置。控件的位置可以

通过设置控件的水平、竖直方向上的对齐属性来设置。

另外一种控制控件元素位置的方式是组合对象。组合对象可以让你在水平方向和在竖直方向上一样布局控件。组合对象还可以实现在组合范围内保持控件之间间距。组合对象没有默认

的视觉效果,但如果需要的话你也可以配置背景色或是背景图片。

5-1

展示了如何在

Storyboard

里面放置不同的控件。前三个控件是标签,每个标签都占满了其所在行的横向区域。对于每个标签,它们的对齐属性决定相对于视图控制器的边界左对

齐、右对齐还是居中。标签的下面是由水平方向上排练的两张图片组成的组合对象。在组合对象的下面还有竖直放置的一条分割线和一个按钮。

5-1

Xcode

里的界面对象

Xcode

中创建界面的时候,尽可能让控件自适应大小。

App

的界面需要被展示在所有尺寸的

Apple Watch

上。让系统去适配界面,尽量减少为不同设备而写的适配代码。

适配不同的显示尺寸

Xcode

支持为不同大小的

Apple Watch

定义不同的界面。在

Storyboard

里面的改动默认会应用到所有不同大小的

Apple Watch

,你也可以根据需要为不同的设备定义不同的

Scene

。比

如,你可能需要为不同的设备调整控件之间的间距和布局以及设置不同的图片。

为不同大小的设备自定义控件需要用到属性面板上的加号按钮来改变默认的设备信息。点击加号按钮为相应的属性增加对应的设备。改变这个值只会影响当前选中的设备。图

5-2

说明

了如何为

42mm

Apple Watch

设置特殊的字体大小。

5-2

为不同的设备自定义控件属性

不应该让用户发现你的

App

在不同大小的

Apple Watch

上有不同的界面,因此建议尽可能不要为不同的设备定义不同的界面。尽量限制因间距、边距等改变视图布局的做法。不推荐因

为不同的布局而移除当前界面上所有控件的做法。你应该尽可能为所有的

Apple Watch

使用相似的界面。

如果要预览不同大小设备上的界面效果,用

Storyboard

编辑区域的控制按钮在不同大小设备间切换。

Storyboard

编辑区默认显示任意大小的设备。改变任意大小模式切换到其它所有尺

寸的

Apple Watch

。如果你讲显示模式切换到了某一个具体的大小,此时你所做的改动只会影响该大小对应的设备。

运行时更新界面

运行时,视图控制器可以修改

Scene

中相关对象的以下以下属性:

设置或更新数据值。

改变控件支持的视觉效果。

改变控件的大小。

改变控件的透明度。

显示、隐藏控件。

不能添加新的控件或是改变已有控件的顺序。尽管你不能移除控件,但是你可以隐藏他们,这样会临时将控件从布局中移除。当所有的控件都隐藏时,其它对象会充满原先这些控件所

在的地方。如果要隐藏某个控件而不让其它对象充满该控件所在的位置,你可以把该控件的

alpha

值设置为

0

。更多关于隐藏控件的内容请参考

Hiding Interface Objects

设置

App

的主色

每个

WatchKit App

会有一个相关的主色,这个颜色会在以下

UI

控件上体现出来:

状态栏上的标题。

通知界面上的

App

名称。

主色存储在

App Storeyboard

里面的一个全局颜色变量里面。要访问这个变量,选中

Storeyboard

,并且选择文件面板。从弹出菜单上选择一个预定义好的颜色,或者用颜色选择器选择

一种自定义的颜色。

界面国际化

WatchKit App

关联的

Storyboard

默认就有基本的国际化。会将

Storeyboard

种所有的字符串自动添加到工程的

Localizable.string

文件中。你只需在该文件中将字符串翻译成需要

的语言,然后就可以在

App

中使用了。当运行时创建了一个

Scene

Xcode

会将字符串关联上相应的本地化语言。

合理布局界面,以便标签等控件有合适的控件来显示它们的文字。不要把按钮都放在同一行,而是应该把它们竖直放置,以便都有合适的空间显示按钮标题。

至于那些你编码中用到的文本和图片,用类似

iOS

OS X App

上国际化的方式:

NSLocalizedString

宏从资源文件中加载字符串。

NSNumberFormatter

对象格式化数值。

NSDateFormatter

格式化日期

WatchKit

扩展里面,

NSLocale

对象返回配置在

Apple Watch

里面的本地化信息。用这个类获取当前用户的首选语言及其它语言还有其它本地化相关信息。

更多关于

App

国际化的内容请参考

Internationalization and Localization Guide

界面导航

对于那些不只一屏内容的

WatchKit App

来说,你必须选择一种在界面之间导航的方式。

WatchKit App

支持两种完全不一样的导航方式:

翻页模式

这种方式适合那些数据模型较简单的

App

,每页的内容和其它页面没有什么关联。翻页模式界面包含两个或更多的相互独立的视图控制器,但任何时候只有一个是可以

被显示的。

App

运行时,用户通过在屏幕上左右滑动来切换不同的界面。在屏幕下方有小点来指示用户当前页面所在的位置。

层级模式

这种方式适合数据模型较复杂或是数据结构有一定层级关系的

App

。层级模式的一般都是基于一个根视图控制器,在这个控制器里面你可以提供一个按钮,点击之后推

出一个新的视图控制器来显示在屏幕上。

尽管你不能在

App

里面混合使用两种导航方式,但你可以在层级模式里面使用模态视图。模态视图是一种打断用户正常浏览流程来要求用户输入或是展示信息的一种方式。在翻页模

式和层级模式中都可以使用模态视图。模态视图本身可以包含一个视图控制器或是包含多个基于翻页模式的控制器。

实现翻页模式界面

通过在

App

Storyboard

里面创建从一个视图控制器到下个视图控制器的

next-page

类型的

segue

来设置使用翻页模式。

在视图控制器之间创建

next-page segue

Storyboard

里面为你的每个页面添加视图控制器。

按住

Control

键点击

App

的主视图控制器不放,然后拖动到另一个视图控制器。

放开鼠标按键。

segue

类型面板选择

“next page”

类型。

用同样的方法在其它界面之间创建

segue

。你设置

segue

的顺序决定了界面上的显示顺序。

你在

Storyboard

里面定义的

segue

会在

App

启动的时候加载。你可以通过在程序启动的早期调用

reloadRootControllersWithNames:contexts:

方法来动态设置你要显示的页面集。比如你可

以在主视图控制器的

init

方法里面调用以上方法来强制

WatchKit

加载其它的视图集。

所有翻页模式的视图控制器都是在界面显示之前就被创建并初始化好的,但一次只能显示一个。一般来说,

Watchkit

显示初始化序列中的第一个视图控制器。如果要改变初始显示的页

面,在

init

或是

awakeWithContext:

方法中调用

becomeCurrentPage

方法。

用户从一个界面导航到另一个界面的同时,

WatchKit

负责激活、取消激活相应的视图控制器。在切换过程中,当前显示的视图控制器的

didDeactivate

方法会被调用,接着会调用下一

个将要显示的视图控制器的

willActivate

方法。通过视图控制器的

willActivate

方法来跟新显示最近的数据改变。

实现层级模式界面

在层级模式界面,你通过

segue

告诉

WatchKit

什么时候跳转到新的页面,或是调用当前视图控制器的

pushControllerWithName:context:

方法。在

Storyboard

中你从一个视图控制器上的

一个按钮,控件组,或是列表中的一行创建

push segue

到另一个视图控制器。如果你喜欢用编程的方式实现

push

,在任意视图控制器的

action

方法中调用

pushControllerWithName:context:

push

一个新的视图控制器到屏幕上的时候,建议通过

pushControllerWithName:context:

方法的

context

参数传入一个数据对象,通过这个对象可以新的视图控制器在显示之前

可以获取一些状态信息,同时通过这个对象告诉新的视图控制器哪些数据需要被显示。

push

出来的视图控制器会在屏幕的左上角有一个

“<”

标志来提醒用户可以导航回去。当用户点击屏幕左上角或是在屏幕上左滑,

WatchKit

会自动隐藏最上面的视图控制器。你也可

以通过调用

popController

方法来编程实现返回,但你不能使

App

的主视图控制器消失。

显示模态视图

模态界面通常是临时打断用户的正常浏览来提示或是显示信息。无论你

App

用的是什么导航方式,都可以在任何视图控制器上显示模态视图。要模态的展示一个视图控制器,可以使

用以下方法中的任意一个:

Storyboard

中创建

modal segue

调用

presentControllerWithName:context:

方法展示一个模态视图。

调用

presentControllerWithNames:contexts:

方法展示基于翻页模式布局的两个或两个以上的视图。

创建一个

modal segue

,连接到你想要显示的视图控制器。如果需要用

segue

显示多个视图,首先用

next-page segue

把需要模态展示的视图控制器连接在一起,这样你就把这些视图控

制器用翻页模式组织在一起了。再用

modal segue

连接到控制器组的第一个控制器上。如果

modal segue

连接到中间的某个控制器上,那么这个控制器之前的视图将不会显示。

模态视图的左上角显示了视图控制器的标题。当用户点击该标题时,

Watchkit

会让模态界面消失。因此最好设置有关闭模态界面提示意义的标题。例如,当显示信息的时候,可以设置

Done

Close

,如果没有为视图控制器设置标题,

WatchKit

默认显示

Cancel

界面对象

您通过界面对象操作你的

WatchKit app

UI

。界面对象是

WKInterfaceObject

类或者更明确的说是它的子类的实例。

WatchKit

框架为大部分(但不是全部)可视化元素提供了界面

对象,您可以在

storyboard

中添加到你的

UI

上的。界面对象不是视图。它们是与真实的视图进行无线通信的代理对象,用以实现

Apple Watch

上的

UI

>

注意

界面对象与

Apple Watch

上相对应的视图的通信是单向的,信息从

WatchKit

扩展传递到

Apple Watch

。换句话说,您可以设置一个界面对象的属性值但是不能获得属性的当前值。在对

设备状态进行改变的时候从

Apple Watch

上获取数据对性能和延迟均有影响。所以建议您在

WatchKit

扩展中保存界面的配置信息。

创建界面对象

通过在界面控制器中添加声明的属性并与

storyboard

文件中相对应的元素连接可以间接地创建界面对象。你不需要自己

alloc

或者

init

界面对象。在界面控制器对象初始化过程中,

WatchKit

自动为已连接的

outlet

创建界面对象。

当给界面对象添加属性的时候,在声明中设置合适的类的类型并且包含

IBOutlet

关键字。举个例子,一个标签(

label

)声明如下:

// SWIFT

class MySwiftInterfaceController {

@IBOutlet weak var label: WKInterfaceLabel!

}

// OBJECTIVE-C

@interface MyHelloWorldController()

@property (weak, nonatomic) IBOutlet WKInterfaceLabel* label;

@end

连接界面控制器中声明的属性与

storyboard

中相对应的项目。快速创建属性声明并与项目相连接的方法是利用

Xcode

中的辅助编辑器。显示辅助编辑器之后,按住

control

键从

storyboard

中的元素拖线到您的类定义的界面中来创建

outlet

。(在

Swift

中,拖线到您的类定义中。)定义了

outlet

的名字之后,

Xcode

在类中创建这个属性的声明并且与

storyboard

中的元素进行了连接。

在设计时配置界面

在设计的时候,用

Xcode

配置

storyboard

中可视化元素的外观。对于许多布局相关的属性,设计时间(

design-time

)是您唯一可以配置属性的机会。举个例子,您可以通过

WKInterfaceLabel

对象改变一个标签的文本、颜色和字体,但是不能改变行数或者每一行的行高。这些属性必须在

Xcode

中配置,如图

7-1

所示。

7-1

配置一个标签对象

图片

2.3

配置一个标签对象

关于更多如何配置界面对象的信息,请看在

WatchKit Framework Reference

中对应的类型描述。

运行时更改界面

WatchKit

扩展的代码中,您可以调用任何引用的界面对象的方法来更新应用程序的

UI

。界面控制器只有在活跃状态下可以改变界面对象的配置,这也包括初始化的时候。在

init

awakeWithContext:

以及

willActivate

方法中,调用方法给标签、图片和其他用户界面中的对象赋值。您也可以在界面控制器的动作方法中更新它们。

在初始化的时候,

WatchKit

在做其他事情之前先初始化界面控制器类这是很重要的。通过

WKInterfaceController

及其子类的初始化方法,

WatchKit

可以为应用程序创建界面对象。所以

您在界面控制器中写的任何初始化代码必须首先调用父类的实现。清单

7-1

显示了一个包含一个

outlet

(称为

label

)的

WKInterfaceLabel

对象的界面控制器的

init

方法。

清单

7-1

初始化界面一个控制器

// SWIFT

override init {

// Initialize variables here.

super.init

 

// It is now safe to access interface objects.

label.setText("Hello New World")

}

// OBJECTIVE-C

- (instancetype)init {

// Always call super first.

self = [super init];

if (self){

// It is now safe to access interface objects.

[self.label setText:@“Hello New World”];

}

return self;

}

为了提高性能和延长电池寿命,

WatchKit

框架优化了在应用程序界面对象上设置值的意图。在同一

Run Loop

循环中,不管你何时设置一个或多个界面对象的值,这些值都会被打包传

Apple Watch

并作为单个批处理以提高效率。合并这些属性意味着对象的给定的属性最后一次更改才能发给设备。更重要的是,如果给同样的属性设置了相同的值,那么会生成一条

日志信息,以便你跟踪重复调用。

关于您用来配置界面对象的方法信息,请看

WatchKit Framework Reference

中相对应的类说明。

响应用户交互

用按钮、开关已经其他的交互控件来改变应用程序状态。当点击按钮或者其他控件的值改变的时候,

WatchKit

会调用界面控制器中相关联的动作方法。每种类型界面对象对于它的动

作方法都有一个必须的格式,表

7-1

已经列出。可以改变动作方法的名称来匹配您的应用程序。

7-1

界面对象的动作方法

Object

Objective-C

Swift

Button

- (IBAction)buttonAction

@IBAction func buttonAction()

Switch

- (IBAction)switchAction:(BOOL)on

@IBAction func switchAction(value: Bool)

Slider

- (IBAction)sliderAction:(float)value

@IBAction func sliderAction(value: Float)

Menu Item

- (IBAction)menuItemAction

@IBAction func menuItemAction()

当界面包含

table

的时候,可以用

segue

或者界面控制器的

table:didSelectedRowAtIndex:

方法来响应点击表中一行。用

segue

显示另一个界面控制器。在执行

segue

之前,

WatchKit

调用

界面控制器的

contextForSegueWithIdentifier:inTable:rowIndex:

或者

contextsForSegueWithIdentifier:inTable:rowIndex:

方法当显示界面控制器的时候你可以指定上下文数据来用。如果你用

table:didSelectedRowAtIndex:

方法而不是

segue

,当点击行的时候,您可以执行任何动作。

当界面控制器初始化完成并且在屏幕上显示之后,只有用户与您的界面交互的时候,

WatchKit

才调用界面控制器的方法。如果在没有用户交互的情况下更新数据,你必须配置

NSTimer

对象,用它的处理器来执行任何需要的任务。

这些任务可能会耗费一到两秒的时间,可以考虑将其交给父级

iOS

应用来执行。长时间运行的任务比如网络连接和定位最好交给父级应用,然后通过共享组容器字典将信息传回给

WatchKit

扩展。关于将任务切换给父级应用的信息,请看

Communicating Directly With Your Containing iOS App

隐藏界面对象

通过隐藏对象可以让您用同一界面控制器显示不同类型的内容。每个

storyboard

文件中的场景必须包含所有在运行时需要显示其内容的界面对象。如果您基于可利用的数据自定义界

面,可以隐藏不需要的对象。隐藏一个对象可有效得将其从界面移除。在布局的时候,隐藏项目可以当做将其从布局中完全删除。隐藏对象,调用它的

setHidden:

方法并设置值为

YES

文本与标签

如需在

WatchKit

应用中显示一段文本,请使用标签对象。标签支持格式化文本,并且可以在运行时用代码改变文本内容。

拖动标签对象到对应的

storyboard

场景中便可添加标签对象。然后便可设置标签的初始化的文本以及格式。

WatchKit

同时支持标准字体和自定义字体。图

8-1

展示了标准字体风格的使

用。

**

8-1 **

使用标准字体风格的标签

图片

2.4

使用标准字体风格的标签

更多的设置标签的相关信息,请参照

WKInterfaceLabel

类参考

使用字体

WatchKit

应用,

glance

界面以及通知界面使用标准字体来显示文本。你应用中的

Controller

可以使用自定义字体来显示文本。

(glance

和通知界面无法使用自定义字体

)

为了让你的应用

使用自定义字体,你必须安装相应的字体,如下:

把你的自定义字体文件包含到

WatchKit

应用以及

WatchKit

扩展

Bundle

里。

WatchKit

应用的

Info.plist

文件添加

UIAppFonts

关键字并指向你添加的自定义字体。更多关于

UIAppFonts

关键字的相关信息,请参照

信息属性列表关键字参考

>

重要

为了能在运行时用自定义字体创建相应的字符串,你必须把自定义字体包含到你的

WatchKit

扩展中。

attributed string

发送到

Apple Watch

的时候,相应的字体信息也包含在其中。你

WatchKit

应用

bundle

中的自定义字体便可以对字符串进行渲染。

使用自定义字体来格式化文本时,需要创建一个包含字体信息的

attributed string

并把它设给标签,如代码

8-1

所示。字体名称和大小被编码到

attributed string

,

然后会被用来更新

Apple Watch

上的标签

.

如果定义的字体名称不符合系统字体或者你安装的自定义字体的名称,

WatchKit

会自动使用系统的字体。

代码

8-1

在标签中使用自定义字体

//

用自定义字体的信息设置

attributed string

 

let menloFont = UIFont(name: "Menlo", size: 12.0)!

var fontAttrs = [NSFontAttributeName : menloFont]

var attrString = NSAttributedString(string: "My Text", attributes: fontAttrs)

 

//

把文本设给标签对象

self.label.setAttributedText(attrString)

管理文件输入

WatchKit

为获取用户文本输入提供了一个标准的模式界面。界面允许用户通过语音或者选择标准短语以及表情等来进行输入。你可以通过调用当前处于激活状态的

Controller

presentTextInputControllerWithSuggestions:allowedInputMode:completion:

方法来显示输入界面

.

界面显示时,你可以指定输入类型并且可以使用一个

block

来处理结果。你也可以指定一个

或者多个初始化短语用来显示在界面上,如图

8-2

所示。用户可以从可用短语中选择或者输入其他短语。

8-2

收集用户的文本输入

图片

2.5

figure8-2

代码

8-2

展示了如何配置文本输入

Controller

并处理结果

.

在指定初始化短语和输入模式后,

Controller

以异步的方式加载。当用户选择了某一项或者取消了输入后,你的

block

会在主线

程中执行。使用

block

来获取用户选择的文本或者表情图片并且刷新你的应用。

代码

8-2

NSArray *initialPhrases = @[@"Ley's do lunch," @"Can we meet tomorrow?", @"When are you free?"];

 

[self presentTetxInputControllerWithSuggestions:initialPhrases allowedInputMode:WKTextInputModeAllwAnimatedEmoji completion:^(NSArray *results){

if(results && results.count > 0){

id aResult = [results objectAtInde:0];

//

使用字符串或者图片

}else{

//

用户没有选择任何东西

}

}];

 

```

 

文本多语言化

 

WatchKit

可以使用与

iOS

应用相同的方法来处理多语言环境。

 

*

storyboards

xib

文件中使用

Xcode

的多语言环境支持。多语言环境让你可以仅使用一个

storyboard

文件便能支持各种本地化语言。

storyboard

使用的本地化字符串储存在指定语言的

字符串文件中。

 

*

使用

NSLocalizedString

类的宏定义来动态获取本地化字符串。

*

使用

NSNumberFormatter

类可以通过用户的时区和场景设置来格式化数值。

*

使用

NSDateFormatter

类可以通过用户的时区和场景设置来格式化时间和日期。

 

 

对你的应用进行多语言化处理的时候

需要考虑的一个主要问题是安排好你的界面以使标签以及其他显示文本的控件有足够的显示空间。比如

当需要放置三个按钮控件的时候

纵向摆放会比横向摆放更妥当。

纵向摆放可以在文本变长的时候提供更多的空间给按钮。

 

更多关于应用的多语言化

请参照

多语言和本地化指南

图片

 

WatchKit

提供了下列方法把图片合并到内容

 

-

WKInterfaceImage

表示一个图像或图像序列。

  

-

WKInterfaceGroup

WKInterfaceButton

WKInterfaceController

类允许您指定一个图像作为其他内容的背景。

 

指定图像资产

    

 

当创建图像资产时请遵循以下建议

 

-

尽量使用

PNG

格式的图像。

-

请创建大小适当的图像。对于无法控制尺寸的图像

请使用

setWidth:

setHeight:

接口对象的方法

以确保图像以合适尺寸显示。

-

使用图像资产来管理图像。图像资产允许为各设备尺寸指定不同图像版本。

 

使用命名图像以提高性能

 

 

下列方法可以改变接口对象的当前图像

 

-

使用

setImageNamed:

或者

setBackgroundImageNamed:

方法来配置存于

WatchKit

应用程序包或设备缓存中的图像。

通过名称指定图片是首选方法

因为名称字符串会传输到

Apple Watch,

这样会花费更少的时间和能量。

WatchKit

会搜索

WatchKit

程序包找到指定名称的图像文件。如果未曾找到

就会搜索

device-

side

图像缓存以查找指定名称的图像。

-

使用

setImage:

setImageData:

setBackgroundImage:

 

setBackgroundImageData:

方法把图像数据从

WatchKit

扩展无线传输到

WatchKit

应用程序。

 

当在扩展中创建

UIImage

对象时

图像对象需保存在用户

iPhone

且使用前要发送给

Apple Watch

。使用

imageNamed:

方法从

WatchKit

扩展包而不是

WatchKit

应用程序来加载图像。如果

试图将该图像分配给接口对象

图像数据会通过无线传输到苹果手表。

 

缓存设备上的图像

  

 

对于在

WatchKit

扩展中创建的频繁使用图像

会在设备中根据名称缓存图像。在调用

WKInterfaceDevice

中的

addCachedImage:name:

addCachedImageWithData:name:

方法使用图像之前

需要进行图片缓存。

 

 

要使用接口中的缓存图片在你的界面

请执行以下操作

 

-

针对

WKInterfaceImage

对象

请调用

setImageNamed:

方法来指定缓存图片的名称。

 

-

针对

WKInterfaceGroup

WKInterfaceButton

对象

请调用

setBackgroundImageNamed:

方法来指定缓存图片的名称。

 

>

重要

当缓存动画图片时

使用

animatedImageWithImages:duration:

方法用所有的动画帧和缓存图片来创建一个单独的

UIImage

对象来。不要用单独地个性的帧来缓存图片。

 

Apple Watch 

图像缓存尺寸受限

每个应用程序拥有大约

5 MB

的缓存空间。当应用程序占用缓存后

添加新图像之前就必须从缓存中移除现有图像。使用

removeCachedImageWithName:

方法来删除

单个图像或使用

removeAllCachedImages

方法来彻底清除缓存。

 

Tables

 

使用

tables

来显示整列动态改变的数据。

WatchKit

支持单列

Tables(

使用

WKInterfaceTable

)

。以表格的形式显示数据要求预先定义显示数据的布局并且在运行时把数据填充到表格中。具体来说

你需要在你的项目中做以下事情

 

-

storyboard

文件中

-

添加

table

对象到你的

Controller

场景中。给

table

对象创建一个输出口

outlet)

-

依照

配置你的行类型

中描述的方式来配置你表格中的行控制器

.

-

在代码中

:

-

定义一个行控制器类用以操作创建的表格的每一行

(

配置行类型

)

-

在初始化的时候添加行到表格

(

运行时配置表格内容

)

-

实现事件输入反馈

(

处理行选择

)

 

你可以给表格定义多种类型的行控制器

每一个都可以有不同的外观。你可以在运行时确定所需的行控制器类型以及他们排列的顺序。更多相关的信息

请参照

WKInterfaceTable

类参考

.

 

配置行控制器

 

行控制器是用来显示你表格内单一行数据的模板。每个表格需要一个或者多个行控制器。比如

你可以用不同的行控制器来显示表格主要内容

表格头

表格尾。当添加一个新的表格到场景中时。

Xcode

会自

动创建一个初始化的行控制制器

,

稍后你可以添加更多其他的行控制器

.

 

给表格添加行控制器

 

1.

Storyboard

中选中表格对象

.

2.

打开属性探测器

(Attributes inspector).

3.

Rows

属性来改变可用的行控制器的数量

.

 

每一个行控制器都有一些初始化元素。你可以把你需要的

比如标签

图片或者其他对象添加到行中。标签和图片的内容在设计的时候是无关紧要的。在运行时

你可以在对行进行配置的时候把内容替换掉。

 

每一个行控制器都由一个自定义类支持

你可以用这个类来接入行的内容。大部分行控制器都只包含与行的

UI

控件相关的属性

,

基本上是没有代码的。然而

当你给行添加按键或者其他可交互的控件时

你的行

控制器的相关类也可以包含对这些交互事件响应的相关方法。

 

给行控制器定义自定义类

 

1.

添加一个

Cocoa Touch

类到你的

WatchKit

扩展中

2.

让你新创建的类继承自

NSObject

3.

把运行时需要接入的属性

如标签

图片等添加到类中。确保这些属性使用以下的格式

保证属性的类型和对应的界面上的控件类型相同

@property (weak, nonatomic) IBOutlet WKInterfaceLabel *label; //Objective-C

 

以下是一个简单的行控制器类的定义

这个例子中

类包含了一个图片和一个标签的输入口。

SWITT class MainRowType: NSObject { @IBOutlet weak var rowDescription: WKInterfaceLabel! @IBOutlet weak var rowIcon: WKInterfaceImage! }

 

OBJECTIVE-C @interface MainRowType : NSObject @property (weak, nonatomic) IBOutlet WKInterfaceLabel* rowDescription; @property (weak, nonatomic) IBOutlet WKInterfaceImage*

rowIcon; @end

 

创建类并且连接输入口到对应控件上后

你的行控制器的配置就完成了。你必须给行分配一个标示性字符

以便在创建行时使用。

 

storyboard

中配置行控制器

 

1.

storyboard

选中行控制器对象。

2.

给行控制器设置一个唯一的标示性标签。稍后创建表格行的时候会用到标示。这个值必须确保在行类型中是唯一的

除此之外没有其他限制。在属性探测器中设置这个标示。

3.

把这个行控制器的类设成你的自定义类。并在

Identifty Inspector

中设置标示。

4.

创建并连接标签以及其他元素的输入口

运行时

,WatchKit

需要这些信息来创建行的界面对象。

 

10-1

展示了一个由代码

10-1

定义的标示为

mainRowType

类为

MainRowType

的行控制器。输入口

rowDescription

rowIcon

分别连接到行中的图片和标签对象。

 

10-1

检查

Xcode

中的行控制器

 

图片

2.6

figure10-1

 

运行时配置表格内容

 

运行时

你可以动态添加行到表格中

并且配置它的内容。

add and configure rows as part of your interface controller's initialization process.

 

创建并配置表格中的行

 

1.

基于你需要展示的数据来确定行的数量和类型

2.

使用

setRowTypes:

setNumberOfRows:withRowType:

方法来创建行。两个方法都可以在

WatchKit

扩展中创建行并且实例化行所对应的类。实例化后的类储存在表格中

可以通过

rowControllerAtIndex:

方法接入。

3.

使用

rowControllerAtIndex:

方法来对行进行迭代。

4.

使用行控制器对象来配置行的内容

 

setRowTypes:

setNumberOfRows:withRowType:

方法对对应的行控制器相关联的类进行实例化。调用这两个方法后

会立即获取最新创建的行控制器对象并用它来配置行。代码

10-2

展示了一个简单

的使用提供的数据对行的标签和图片进行配置的例子。数据由一个自定义数据类型

MyDataObject

组成的数组提供。

MyDataObject

类有一个字符串和一个图片属性

它的实现这边没有展示出来

行本则是

自定义类型

MainRowType

类的实例。

 

代码

10-2

创建并配置表格的各行

- (void) configureTableWithData:(NSArray *) dataObjects{ [self.table setNumberOfRows:[dataObjects count] withRowType:@"mainRowType"]; for(NSInteger i = 0; i < self.table.numberOfRows; i

++){ MainRowType *theRow = [self.table rowControllerAtIndex:i]; MyDataObject *dataObj = [dataObjects objectAtIndex:i]; [theRow.rowDescription setText:dataObj.text]; [theRow.rowIcon

setImage:dataObj.image]; } }

 

配置表格时

你可以限制初始化时行的数量来提高性能。由于表格的行都是必须在前台创建的

,

如果创建的数量过大会严重影响你应用的性能

.

具体的数量限制取决于你数据的复杂程度以及创建行需要的时间

建议把总数量限制在

20

以下。对于需要更多行的表格

可以考虑在初始化的时候只加载一部分行

并提供给用户可控制的展示更多行的方法。更好的解决方案是指显示最重要的那几行。比如

你的数据为定位数

据的时候

把数据限制到和用户当前位置相关的那几行。

 

处理行选择

 

界面控制器可以用来处理它所持有的任意表格的行选择事件。当用户点击表格上的某一行时

WatchKit

会选中那行并调用控制器的

table:didSelectRowAtIndex:

方法。使用这个方法来执行相关的行为。

比如

你可能需要展示一个新的界面控制器或者刷新行的内容。如果你不需要某一行处于可选状态

可以在

storyboard

中把对应的行控制器的

Selectable

选项取消。

 

上下文菜单

 

Apple Watch

Retina

屏的

Force Touch

提供了一种新的与内容交互的方式。与点击屏幕上的项目不同

该特性需要一定的压力才能激活与当前界面控制器相关的上下文菜单

如果有的话

。上下文菜

单是可选择的。您用上下文菜单显示与当前屏幕相关的操作。

WatchKit

在内容之上显示菜单

如图

11-1

11-1

一个包含三个项目的上下文菜单

上下文菜单可以显示多达

4

个动作

action

。每个动作由一个标题和一张图片表示。点击某个动作的图片会关闭菜单并执行相应的方法。点击屏幕上其他的地方只能关闭菜单。

设计菜单项

每个菜单项包含一个可点击区域和一个标题。可点击区域包括圆形背景

顶部是您所提供的图片。这张图片必须是模板图片

alpha

通道决定了绘制在背景顶部的形状。图片的不透明部分显示为黑色

全部

或者部分半透明可透出背景颜色。

您所提供的模板图片应当比它们所在的圆形背景要小一点。关于菜单图片的尺寸和创建图片指南的更多信息

请参考

Apple Watch Human Interface Guidelines

为界面控制器添加上下文菜单

您可以在设计时配置界面控制器的上下文菜单

但是也可以在运行时添加和移除菜单项。在设计时

编辑

storyboard

包括您想在指定的界面控制器上显示的菜单项。当之后初始化界面控制器的时候

您可以

添加菜单项来补充在

storyboard

中所创建的。通过代码创建的菜单项也可以删除。不管您是在

storyboard

中拖入菜单项还是通过代码添加

菜单中的菜单项不能超过

4

个。

在界面控制器中添加上下文菜单

1.

打开

storyboard

文件。

2.

从工具库

library

中拖拽一个菜单对象并添加到界面控制器场景中。

最初的菜单包含一个单独的菜单项。

3.

最多从工具库中拖拽

3

个菜单项到菜单中。

您也可以用菜单的属性检查器

Attributes inspector

来设置菜单项的数量。您所添加的菜单项不能通过编程删除。

4.

对于每一个菜单项

用属性检查器

Attributes inspector

指定菜单的标题和图片。两者都是需要的。

5.

在界面控制器类中将每个菜单项与操作方法连接起来。

菜单的操作

action

方法有以下格式

- (IBAction)doMenuItemAction

6.

保存

storyboard

文件。

 

想要在运行时添加菜单项

调用界面控制器对象的

addMenuItemWithImage:title:action:

或者

addMenuItemWithImageNamed:title:action:

方法。您指定的菜单项被附加到

storyboard

文件的菜单中。通过编程方式一直附属于菜单直到你明确移除它们或者界面控制器被销毁。

 

处理菜单项的点击

 

当用户点击菜单项时

WatchKit

关闭菜单并调用相关的动作方法。您可以在界面控制器中通过下面的语法来定义动作方法

// SWIFT @IBAction func doMenuAction() { // Handle menu action. }

 

// OBJECTIVE-C - (IBAction)doMenuItemAction { // Handle menu action. }

 

如果要求使用任何状态信息来执行操作

那您需要在界面控制器中存储并保持这些信息。举个例子来说

如果一个动作依赖于表的当前选中行

您的界面控制器必须包含一个变量来跟踪当前选中行。如果您需要

用户点击菜单动作之后的更多信息

那动作方法必须显示一个模态界面控制器。

 

 

 

设置

 

参数和设置是变动较少的数值

可以用于配置应用程序的行为或外观。如果

WatchKit

应用程序使用参数进行配置

就可以在工程中添加一个

WatchKit

专用设置包来显示这些设置。此设置包置于

iOS

用程序中

而设置本身会在用户手机上显示。

 

WatchKit

设置包与

iOS

设置工作包的工作流程相同。此设置包定义了系统控件和各控件修改的参数名称。用户手机的

Apple Watch

应用程序会获取设置包信息以便显示实际控件。当用户更改控件数值

系统会更新底层参数值。

 

如需获取设置包工作的详细信息

请参考

Preferences and Settings Programming Guide

 

创建

WatchKit

设置包

 

 

请按照以下操作向

Xcode

项目添加

WatchKit

设置包

 

1.

选择

File > New > File

2.

Apple Watch

选项中选择

WatchKit

设置包并单击

Next

3.

使用

Settings-Watch.bundle

名称来创建设置包

并添加到

iOS

应用程序中。命名

Settings-Watch.bundle

包是为了与

iOS

应用程序包进行区分。

 

 

WatchKit

设置包的初始内容与

iOS

应用程序设置包相同

详见清单

12-1

 

清单

12-1 WatchKit

设置包的内容

Settings-Watch.bundle/ Root.plist en.lproj/ Root.strings

 

关于如何配置设置包内容

请查看

Implementing an iOS Settings Bundle

。有关设置包的详细信息

请查看

 

Settings Application Schema Reference

 

允许访问

WatchKit

扩展的参数值

 

WatchKit

设置必须存储在共享组容器中

iOS

应用程序和

WatchKit

扩展均可对其进行访问。因为

WatchKit

设置包位于

iOS

应用程序

,

系统会默认把参数值写入

iOS

应用程序容器。如果想访问

WatchKit

扩展

,

您必须对项目执行以下配置

:

 

- App Group

同时支持

iOS

应用程序和

WatchKit

扩展。

选择相同的组标识符。

-

Root.plist

文件添加

ApplicationGroupContainerIdentifier

键。

 

当配置

App Group

功能时

把此键所对应索引设置为相同的标示符。

不需要把此键放入属性列表。

 

运行状态访问设置

    

 

要想访问存储于一组容器中的参数

请使用

initWithSuiteName:

方法来创建

NSUserDefaults

对象。调用此方法时

请指定组容器标示符所用的字符串。然后使用用户默认对象来访问参数值。下面提供

了访问自定义组的示例

 

清单

12-2

访问一个共享组容器的参数

NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.example.MyWatchKitApp"]; BOOL enabled = [defaults boolForKey:@"enabled_preference"]; ```

如何访问参数的值,更多信息请参考

NSUserDefaults Class Reference

3

预览

预览概要

预览可以作为用户查看应用重要信息的辅助方法。并不是所有的应用都需要一个预览。预览可以及时提供一些相关的信息。例如,时钟应用的预览可以给用户展示下一次会议的时间,

而航空公司的应用可以给用户展示下次航班的登机信息。图

13-1

展示列表示例应用的预览,它显示了已经完成的项目条数和等待完成的项目条数。

13-1

列表示例应用的预览界面

图片

3.1

列表示例应用的预览界面

预览可以看作是手表插件应用和手表插件的扩展。你的预览界面存在于手表插件应用的

storyboard

文件中,界面是由自定义的

KInterfaceController

类来管理。然而,预览界面控制器的

唯一任务是设置预览界面的内容。预览不支持交互,且当触摸到预览界面时,会立即启动手表插件应用。

预览的生命周期

界面预览控制器和其他界面控制器的生命周期是相同的,除了一开始就初始化展现给用户的界面预览控制器。因为在初始化和展示预览之间只要一小点时间就可以完成,包含检查你的

willActivate

方法确保所展示的信息都是最新的。

更多关于的界面控制器的生命周期可以查看

WatchKit Extension Life Cycle

界面预览指导

Xcode

提供了固定的布局来排版你的预览内容。在选择一个布局来为内容使用之后,用下面的指导来填充内容:

设置预览来快速传达信息。

不要显示纯文本框。适当的使用一些图形,颜色和动画来传递信息。

聚焦于重要的信息数据。

预览不是手表插件应用的替代品。就像你的手表插件应用是

iOS

应用的缩小版应用一样,预览则是手表插件的缩小版

App

在预览界面里面不包含交互控件。

交互控件包含

buttons, switches, sliders, and menus

在预览界面中需要避免图表和地图。

然而却不是禁止,在狭小的空间里面使得地图和图表似乎没有什么作用。

及时查看信息显示。

用所有可用的资源,包含时间和位置来提供信息给用户。考虑到在预览界面初始化的时间和显示给用户的时间

之间会有一些变化,你需要记得更新你的预

览。

用系统的字体来展示所有的字体。

如果需要使用自定义的字体到你的预览,你需要渲染文本成为图像之后展示给用户。

因为一个应用只有一个预览控制器,所以一个控制器必须能够展示你需要展示的信息。

管理你的预览界面

当你添加手表插件应用到你的

Xcode

项目时,你可以指定是否想要预览界面。如果你忘记在建项目的时候添加预览界面,你也可以晚点再把它加到你的项目中。一个预览界面控制器

有轻微的不同显示方式在你的应用的

storyboard

上。尤其是,它有一个预览入口对象附属在上面,同时它有一个默认的布局,如下面的图

14-1

14-1

一个带有预览入口对象的界面控制器

图片

3.2

一个带有预览入口对象的界面控制器

你可以用自定义的

WKInterfaceController

的子类去配置运行时的预览内容。实现子类之后,你可以像实现其它手表插件应用中的界面控制器一样去实现它。

添加预览界面到你的应用

当为你的应用创建手表插件时,为了确保预览屏幕选项包含了创建的相关文件,你需要实现的预览界面。

Xcode

提供给你一个预览

storyboard

屏幕和一个自定义的预览界面控制器类。

如果你没有在创建的时勾选这个选项,你可以手动去配置。

手动创建预览界面

1.

在你的项目,创建一个

WKInterfaceController

的子类。创建这些新的资源文件并添加到你的手表插件扩展目标。给这个子类名一个恰当的名字。例如,

GlanceInterfaceController

2.

在你的

storyboard

文件中,拖拽

Glance Interface Controller

到你的

storyboard

这个屏幕展示你的新加入的预览界面控制器就会有一个预览入口对象附属在上面,就如图

14-1

所示。

3.

选择你

storyboard

上的预览界面控制器并打开

Identity inspector

4.

根据步骤

1

去设置你的预览界面控制器类。

手表插件应用有且只有一个预览界面。不要添加更多预览界面控制器到你的

storyboard

上。

实现一个预览界面控制器

实现预览界面控制器是相当简单的,因为只需要设置预览容器的标签和图像。所以你的预览通常只需要实现两个步骤。

使用

init

awakeWithContext:

方法去初始化你的预览界面并设置它的标签和图像的初始值。

根据最近的变化使用

willActivate

去更新预览界面。

使用一个

NSTimer

对象周期地变化更新它在屏幕上预览的内容。你无需更新

WKInterfaceDate

WKInterfaceTimer

对象,因为它们是自动更新的。

定制点击预览之后的启动方式

当用户触摸预览,苹果手表会启动相应的手机插件应用。通常,启动的应用之后会展示它的主界面控制器。如果需要定制点击预览之后的启动方式,按照如下步骤:

在预览界面控制器里:

配置预览界的通用方法

init

willActivate

调用

updateUserActivity:userInfo:webpageURL:

方法,并用

userInfo

属性去传递预览的状态信息给你的应用。在启动的时候,你的应用可以用上下文信息来展示不同的界面控

制器。

在你的主要界面控制器里:

实现

handleUserActivity

方法,用提供的

userInfo

字典去适当配置你的

UI

在启动的时候,调用

updateUserActivity:userInfo:webpageURL:

方法告诉手表插件调用主界面控制器的

handleUserActivity:

方法。用系统提供的的上下文数据适当地配置你的

UI

。例如,一个基于页面的界面应用,可以用这些提供的数据信息去选择初始化时展示哪一页。

4

通知

通知要点

如果你的

iOS

应用程序支持本地或者远程通知,

Apple Watch

会在合适的时候显示这些通知。当一个应用程序的本地或者远程通知被用户的

iPhone

收到后,

iOS

会决定是否将该通知显

示在

iPhone

或者

Apple Watch

上。对于发送到

Apple Watch

的通知,系统会隐约的告诉用户有一个通知了。如果用户选择查看通知,系统会先显示该通知的一个简短版本,之后才是一

个更详细的版本。用户可以选择忽略该通知,也可以启动你的

WatchKit

程序,或者通过通知上的有效活动按钮来触发其他操作。

应用程序不需要做任何事情来支持通知。系统提供了一个默认的通知显示界面来显示提醒信息,不过,应用程序也能自定义通知界面,包括自定义图形,内容和品牌。

>

注意:

只有在

iOS

支持它们的情况下,

Apple Watch

才能显示本地或者远程通知,有关如何支持本地和远程通知你的

iOS

应用程序信息,请查看

Local and Remote Notification Programming

Guide

Short-Look

界面

当用户第一次看到通知的时候,系统会显示一个

short-look

界面,图

15-1

展示的就是样子示例。

short-look

界面是非自定义并且不能滚动的。系统会使用一个模板来显示应用程序的名

字,图标以及存储在本地通知或者远程通知中得标题字符。如果用户继续查看通知,系统将会快速的从

short-look

界面转换到

long-look

界面。

15-1

一个

short-Look

界面

short-look

使用的标题字符串提供了该通知的一个简短的意图指示。对于本地通知,使用

UILocalNotification

对象的

alertTitle

属性指定该字符串。对于远程通知,则在负载数据

中的

dictionary

(字典)里添加一个

title

key

。获取更多关于添加一个标题字符串到你的通知中,请查看

Local and Remote Notification Programming Guide

Long-Look

界面

Long-look

界面是一个能滚动并且显示通知内容以及相关活动按钮的屏幕。如果你没有提供一个自定义的通知界面,

Apple Watch

会显示一个默认的界面,包含你应用程序的图标,通知

的标题以及提示消息。如果你提供了自定义的通知界面,

Apple Watch

则会显示你自定义的界面。

long-look

通知界面由三块区域组成:

sash

(腰带)区域是一个包含了应用程序图标和名称的浮层。

sash

区域在默认情况下是透明的,但是你也能在你自定义的通知界面修改它的颜色。

内容区域包含了通知的具体信息。对于自定义的界面,你可以配置该区域位于

sash

开始位置或者在它的下方。获取更多关于如何自定义内容区域,请查看

Custom Notification

按钮区域包含了

忽略

按钮以及其他

iOS

程序注册的活动按钮。

15-2

展示了一个包含了两个活动按钮的

long-look

通知示例。

15-2

一个

long-look

通知界面

图片

4.2

一个

long-look

通知界面

点击应用程序图标启动

WatchKit

程序。点击程序自定义的活动按钮则会将选择的活动发送到

iOS

应用程序或者你得

WatchKit

应用程序。前台活动被发送到你的

WatchKit

程序和拓展,

后台活动则发送到你的

iOS

程序。点击

忽略

按钮则啥都不做,直接关闭当前通知界面。点击其他地方则什么效果也没有。

更多关于如何为你的应用提供自定义

long-look

界面,请见

Custom Notification Interfaces

为通知添加活动按钮

活动按钮通过为通知提供封装响应为用户节省时间。

Apple Watch

借用

iOS

程序注册的交互通知来显示活动按钮,在

iOS 8

以及更高的版本中,应用都需要使用

UIUserNotificationSetting

对象来注册通知的类型。当注册信息的时候,应用程序同样可以注册一系列自定义通知目录,

Apple Watch

使用这些目录信息将对应的活动按钮添加到

long-

look

界面上。

代码

15-1

片段展示了如何为一个示例

iOS

程序注册设置和目录。这个方法是被包含

iOS

程序实现的,而不是

WatchKit

拓展,并且是在

iOS

程序启动时委托调用的。这个方法的是使用

swift

语言写的,还展示了

“invitation”

目录的创建和注册,

“invitation”

目录包含了接受和拒绝会议邀请的活动动作。

代码

15-1

在包含的

iOS app

中注册

Actions

func registerSettingsAndCategories() {

var categories = NSMutableSet()

 

var acceptAction = UIMutableUserNotificationAction()

acceptAction.title = NSLocalizedString("Accept", comment: "Accept invitation")

acceptAction.identifier = "accept"

acceptAction.activationMode = UIUserNotificationActivationMode.Background

acceptAction.authenticationRequired = false

 

var declineAction = UIMutableUserNotificationAction()

declineAction.title = NSLocalizedString("Decline", comment: "Decline invitation")

declineAction.identifier = "decline"

declineAction.activationMode = UIUserNotificationActivationMode.Background

declineAction.authenticationRequired = false

 

var inviteCategory = UIMutableUserNotificationCategory()

inviteCategory.setActions([acceptAction, declineAction],

forContext: UIUserNotificationActionContext.Default)

inviteCategory.identifier = "invitation"

 

categories.addObject(inviteCategory)

 

// Configure other actions and categories and add them to the set...

var settings = UIUserNotificationSettings(forTypes: (.Alert | .Badge | .Sound),

categories: categories)

 

UIApplication.sharedApplication().registerUserNotificationSettings(settings)

}

>

注意:

更多关于如何在你的

iOS

应用程序中配置目录和活动,请见

Local and Remote Notification Programming Guide

响应活动按钮点击

当用户点击活动按钮时,系统使用注册

UIUserNotification

对象中的消息来决定如何处理这个动作。动作能在前端和后台经过或者不经过验证被执行。不管怎样,前端和后台动作的处

理是不同的:

前端动作会启动你的

WatchKit

程序并且将你点击的按钮

ID

发送到你主控制接口中的

handleActionWithIdentifier:forRemoteNotification:

或者

handleActionWithIdentifier:forLocalNotification:

方法。

后台动作则会在后台启动能处理该动作的

iOS

程序,对应动作的信息将被发送到程序代理的

application:handleActionWithIdentifier:forRemoteNotification:completionHander

或者

application:handleActionWithIdentifier:forLocalNotification:completionHandler

方法。

对于前台按钮动作来说,

WKUserNotificationInterfaceController

子类并不处理这个按钮动作。选中一个前台按钮动作将启动你的应用,并为你应用的主入口点载入界面控制器。该初始

界面控制器负责处理所有按钮动作。这个界面控制器必须实现

handleActionWithIderntifier:forRemoteNotification

handleActionWithIdentifier:forLocalNotification

方法(如果适用的话)

来处理按钮动作。

管理自定义

Long Look

界面

自定义

long-look

通知界面包含两个独立部分,一个是静态的,一个是动态的。静态的界面是必须的,并简单的显示通知的提示信息,它的图片和文字是在设计的时候就配置的。动态

界面是可选的,只是为了让你有方法能自定义显示通知内容。

当你在

storyboard

中创建一个新的通知界面

controller

的时候,

Xcode

只会默认创建一个静态界面,如果你需要创建动态界面,需要在

storyboard

的通知目录对象中选择

“Has Dynamic

Interface”

属性。(只有在静态界面无法满足你需要的时,再选择添加动态界面才是明智的选择)。图

16-1

显示了

storyboard

文件中未修改的静态和动态界面场景。静态和动态场景都

是同一类型的相关通知,你可以使用通知

category

对象附加到静态场景来配置。

16-1

静态和动态的通知界面

图片

4.3

静态和动态的通知界面

当合法的通知类型被接受后,

WatchKit

会基于不同的因素来选择静态或者动态界面。当动态页面不存在,或者当电量不够,又或者你根本就没有明确告诉

WatchKit

显示动态界面的时

候,

WatchKit

会自动显示静态页面。在其他情况下,

WatchKit

会显示你的动态页面。在确定显示动态页面后,

WatchKit

会加载合适的

storyboard

资源然后准备合适的接口。就如图

16-

2

中所描述。

动态界面的加载过程就跟你应用程序中的界面

controller

一样,只是这个是通知界面

controller

特定的用来处理通知负载数据的。

16-2

准备通知界面

图片

4.4

准备通知界面

添加自定义通知界面到你的程序

当你为你的目标应用程序创建

WatchKit

程序时,你需要勾选上

Include Notification Scene

选项来创建对应通知接口的实现文件。

Xcode

提供了一个空的

storyboard

场景和一个用于你通

知接口

controller

的自定义子类。如果你在创建的时候没有选中刚才说的那个选项,而你又需要创建通知接口,则需要手动自己添加。

手动添加通知接口:拖一个通知接口

controller

对象到你的

storyboard

文件。新的接口仅仅只是包含了静态的页面控制器,为了创建动态接口,你必须执行以下配置步骤:

配置动态通知接口

controller

1.

在你的项目中,创建一个新的

WKUserNotificationInterfaceController

子类。

创建新的资源文件并将其添加到你的

WatchKit

拓展目标,然后给你的类一个合适的名字以区别于其他通知接口

controller

2.

勾选通知目录中得

Has Dynamic Interface

,这一步将添加动态场景到你的

storyboard

文件。

3.

设置你动态通知界面

controller

为在第一步创建的类。

应用程序可能有多个通知界面,你可以使用目录(

categories

)来区分。再你得

storyboard

文件中,使用

Notification Category

对象指定

category

名字来关联不同的场景。

WatchKit

使

category

值来决定在运行时加载哪个场景。如果进来的通知没有

category

WatchKit

则加载

category

名为

default

的。更多关于如何指定通知的

category

,请见

Configuring the

Category of a Custom Interface

配置自定义界面的

Category

每个通知接口必须有指定的通知

category

,这样才能告诉

Apple Watch

什么时候使用。发送进来的通知可以在负载数据中包含一个

category

键,值则你自己定义。

Apple Watch

使用

category

来决定显示哪个通知场景。如果进来的通知没有包含

category

字符串,

Apple Watch

显示配置时的默认通知界面。

指定你通知接口的通知类型,在你的

storyboard

中选择

“Notification Category”

对象并选择

Attributes

检查框,如图

16-3

所示。在检查框中得

Name

字段里输入

category

的名字。同时你

也能在这个框中设置你自定义界面的

sash

颜色和标题文字。

16-3

配置通知类型信息

图片

4.5

配置通知类型信息

当生成远程通知时,你的服务器通过在负载数据的

aps

字典里包含一个

category

键来指定通知类型。对于本地通知,你可以通过

UILocalNotification

对象的

category

属性的值

来指定。

>

注意

category

字符串同样也能定义哪些活动按钮(如果有的话)被追加到通知界面的最后,获取更多关于支持自定义活动的信息,请见

Adding Action Buttons to Notifications

配置静态通知界面

使用静态通知界面来定义一个简单的自定义的通知界面,静态界面的目的是为了在你

WatchKit

拓展的事件中提供一个回调接口,

WatchKit

拓展是无法及时配置动态界面的,以下是创

建一个静态界面的规则:

所欲的图像必须位于

WatchKit

应用程序包。

界面不能包含控件,表格,地图或者其他互动元素。

界面的

notificationAlertLabel

出口必须连接到一个

label

,这个

label

的内容设置为通知的提示信息。对于所有其他标签的文字都不要改变,而要再你的

storyboard

文件中指

定。

16-4

展示了在一个日历程序中自定义通知界面的静态和动态场景。通知箭头指向了静态场景,这个场景中包含了一个自定义

icon

和两个

label

。在静态界面中,

label

包含了一个字符

<message>

,它就是跟

notificationAlertLabel

出口相关的,因此它会在运行时收到通知的提示消息。

16-4

一个单一通知类型的静态和动态场景

图片

4.6

一个单一通知类型的静态和动态场景

配置动态通知界面

一个动态通知界面可以为用户提供更加丰富的体验。使用动态界面,你可以显示更多而不仅仅只是提示消息。你可以放置更多的信息,配置更多的

label

,显示动态生成的内容等等。

实现动态的通知界面需要创建一个

WKUserNotificationInterfaceController

的子类。当一个合适类型的通知过来时,这个子类的实现就是用来响应它的。

设计你的动态界面

配置你得动态界面就像其他界面

controller

场景,包括在你的子类中引用的

label

image

和其他场景中的对象。然后使用这些在运行时配置场景内容。点击通知页面启动应用程序,所

以通知界面不应该包含交互控制。

多为你的界面使用

label

image

group

separator

(分离器)。

你可以可以在你的界面中包含

table

map

不要包含

button

switch

或者其他交互控制。

在运行时配置你的动态界面

当一个合适类型的通知到达时,

WatchKit

从你的

storyboard

中选择合适的场景显示并告诉你的

WatchKit

拓展初始化对应

WKUserNotificationInterfaceController

子类。图

16-5

展示了

WatchKit

需要准备你界面的步骤,在初始化通知界面

controller

之后,

WatchKit

使用

didReceiveRemoteNotification:withCompletion:

或者

didReceiveLocalNotification:withCompletion:

方法

来发送有效负载数据,然后你使用负载数据来配置你通知界面的其他部分,然后调用设置完成处理程序块让

WatchKit

知道你的界面已经准备好了。

16-5

配置动态通知界面

图片

4.7

配置动态通知界面

总是使用

didReceiveRemoteNotification:withCompletion:

或者

didReceiveLocalNotification:withCompletion:

方法来配置你的通知界面,当实现了其中任意方法后,已经配置的界面提供的

处理程序会尽快执行完成。如果等得太久,

Apple Watch

会尝试放弃显示你的动态界面而以显示静态界面来代替。

清单

16-1

展示了

didReceiveRemoteNotification:withCompletion:

方法实现的示例。这个方法是通过一个虚构的日历程序,发送一个新的会议邀请远程通知。该方法从远程通知

的负载数据中提取数据并利用该数据来设置通知界面上的

label

值。为简单起见,该示例假定服务器总是为每个

key

都包含了一个合适的值。但你自己的代码应该做一些必要的错误检

查以保证这些负载数据是有效的。在配置完

label

之后,则调用处理程序让

WatchKit

知道自定义的界面以及准备好可以显示了。

清单

16-1

在一个远程通知里配置自定义界面

// Standard remote notification payload keys.

NSString* apsKeyString = @"aps";

NSString* titleKeyString = @"title";

 

// Payload keys that are specific to the app.

NSString* customDataKey = @"cal";

NSString* invitationDateKey = @"date";

NSString* invitationLocationKey = @"loc";

NSString* invitationNotesKey = @"note";

 

- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void(^)(WKUserNotificationInterfaceType interface))

completionHandler {

// Get the aps dictionary from the payload.

NSDictionary* apsDict = [remoteNotification objectForKey:apsKeyString];

 

// Retrieve the title of the invitation.

NSString* titleString = [apsDict objectForKey:titleKeyString];

[self.titleLabel setText:titleString];

 

// Extract the date and time from the custom section of the payload.

// The date/time information is stored as the number of seconds since 1970.

NSDictionary* customDataDict = [remoteNotification objectForKey:customDataKey];

NSNumber* dateValue = [customDataDict objectForKey:invitationDateKey];

NSDate* inviteDate = [NSDate dateWithTimeIntervalSince1970:[dateValue doubleValue]];

 

// Format the date and time strings.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

 

// Call a custom method to get the localized date format string for the user.

// The default date format string is "EEE, MMM d".

dateFormatter.dateFormat = [self dateFormatForCurrentUser];

NSString *formattedDateString = [dateFormatter stringFromDate:inviteDate];

 

// Call a custom method to get the localized time format string for the user.

// The default time format string is "h:mm a".

dateFormatter.dateFormat = [self timeFormatForCurrentUser];

NSString *formattedTimeString = [dateFormatter stringFromDate:inviteDate];

 

// Set the date and time in the corresponding labels.

[self.dateLabel setText:formattedDateString];

[self.timeLabel setText:formattedTimeString];

 

// Set the location of the meeting.

NSString* locationString = [customDataDict objectForKey:invitationLocationKey];

[self.locationLabel setText:locationString];

 

// Set the invitation's notes (if any).

NSString* notesString = [customDataDict objectForKey:invitationNotesKey];

[self.notesLabel setText:notesString];

 

// Tell WatchKit to display the custom interface.

completionHandler(WKUserNotificationInterfaceTypeCustom);

}

在调用完成处理代码块时,如果你希望

WatchKit

显示静态界面,那就指定

WKUserNotificationInterfaceTypeDefault

常量。

>

注意

通知界面的文字仅仅只支持系统指定的文字字体,如果你需要显示其他字体,最好是将文字嵌入图片中,然后显示那张图片。

测试你自定义界面

当你已经准备好在模拟器上测试你的动态界面时,为你的通知界面创建一个自定义运行计划,如果你还没有这么做的话。当你配置界面时,指定一个你希望发送到你的界面并包含测试

数据的

JSON

文件。

Xcode

会为指定的数据提供自定义的

JSON

文件。

更多关于设置运行计划并配置你的数据的信息,请见

The Build, Run, Debug Process

5

更新记录

2015-03-25

修改点

新建项目

贡献者

YouXianMing

vectxi

wangning

wanningliu

7heaven

staker

riverfeng

更多信息请访问

http://wiki.jikexueyuan.com/project/apple-watch-programming-guide/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论