这是WatchKitStoryboard攻略的第三篇,重点自然是Notification(通知)视图这一部分的内容。
首先转述一下有关概念及原理:AppleWatch应用的通知内容是与iPhone应用同步显示的,但分为ShortLook(短时查看)和LongLook(长时查看)两类进行展现。当某iOS应用的本地或远程通知抵达用户的iPhone 后,iOS将会自行判断显示该通知的设备(iPhone或AppleWatch),对于发送到 AppleWatch的通知来说,系统首先会通过TapticEngine触觉反馈提示用户,如果用户抬起手腕选择查看通知,系统将会首先展示该通知的短时概览(ShortLook),如果用户不放下手腕暂停一会后AppleWatch切换进入LongLook模式。而我们观察Storyboard可知通知是分静态和动态两种的,这里特别强调不要想当然的认为ShortLook就是对应的静态通知,ShortLook的通知目前在模拟器是无法测试的,Storyboard配置的静态与动态通知都是针对的LongLook通知,静态标签内容部分来自Notification payload,动态内容部分则来自于自定义WKUserNotificationInterfaceController类。
还要注意系统的限制:iOS系统无法定义一个AppleWatch专用的通知,意味着通知必然是同时发送到iPhone与AppleWatch的,只不过可以针对AppleWatch开发专属的动态通知功能。
我们通过开发一个提供AppleWatch喝水通知的简单示例应用来看看WatchKit提供的Notification有哪些功能。
(教程运行环境:MacOSX10.10、Xcode6.2beta3、Swift)
建立testNoti项目,新添加WatchKit App的target。
复制一份Watch主应用的Scheme以建立Notification模板的启动Scheme。
看一下WatchKit App的Inteface.storyboard:Static Notification InterfaceController Scene对应的是静态通知,Notification ControllerScene对应的是动态通知。
我们可以看到静态通知的CustomClass是无法指定的,其主要界面实现都通过配置Storyboard里相关属性完成。我们对照Main类的Storyboard配置,可以理解为Notification整个模板的界面背景是一个不可见的Group,而且其上方有一层显示通知来源应用名称及其图标的蒙版区域。
与Group组件一样,我们可以设置整个通知的背景图。
假设我们的通知界面设计为一个全屏带提醒文字的蓝色图片背景,首先针对42mm设备,做一个312*352的蓝色圆角矩形底图(高度减去了标题栏部分)并添加文字图案,然后设置一下Background的文件名,模式改为Aspect Fill:
下图是运行效果,同时我们也在图上标注出各项目的对应设置路径。但这样显示不全,还达不到期望的全屏显示的强调效果。
那是因为通知标签高度小了,我们加一个固定高度(这里我们针对42mm设备设置为138)的Group并把Label拖进去,效果已经可以看得到:
接下来设置一下图标,我们简单的做一个宽高88px的作为42mm设备的图标,缩小为80px作为38mm设备图标,并将他们拖入AppIcon对应项
然后是自定义的按钮和通知文本,我们修改WatchKit Extension里的PushNotificationPayload.apns文件中对应内容以测试效果:
运行发现期望的全屏效果已经有了,但按钮需要滚动屏幕才能看到
而点击“Ok I did it”按钮会切换进入AppleWatch应用的主程序,Dismiss按钮则是系统自动生成的。
BTW:程序名称部分的半透明蒙版色彩可以通过修改Notification入口的SashColor属性进行修改。
动态通知在Storyboard部分与静态通知配置方法类似,但我们获得了代码绑定通知界面元素的功能,可以后台动态获取并将其在界面上进行展现。
先测试一下,拖拽一个Label到动态通知控制器上,更改文本为hi:
要将模拟器切换为显示动态通知,必须把Controller代码里这段注释取消:
overridefunc didReceiveRemoteNotification(remoteNotification: [NSObject : AnyObject], withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) { completionHandler(.Custom) }
运行一下,确实可以显示出标签hi了,下面代码绑定此Label控件,
@IBOutletweakvar dynamicLabel: WKInterfaceLabel!
再添加进一步显示喝水量的代码
overridefunc didReceiveRemoteNotification(remoteNotification: [NSObject : AnyObject], withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) { let mount=1.2 //此值根据你的应用计算生成 dynamicLabel.setText("Today you should drink /(mount)L water more.") completionHandler(.Custom) }
最后别忘了在Storyboard里修改dynamicLabel的Lines为3行,以免显示不下
运行即可看到正确的效果。