1.IWatch 的API
2.API的功能
3.通讯机制
4.UI
1.watch的API及功能
WatchKit 框架
WKInterfaceController
生命周期
//初始化watch的UI,生成对应的controller,并且响应init方法
- (instancetype)initWithContext:(id)context;//加载数据或者更新当前Controller添加的interface objects
//显示当前加载的UI时
- (void)willActivate;//更新interface objects或者处理其他事件
//当用户切换页面或者停止使用时
- (void)didDeactivate;//应该在这里清理task或者数据,更新将会被系统忽略
页面跳转(两组)
第一组 (和UIViewController类似)
- (void)pushControllerWithName:(NSString *)name context:(id)context
- (void)popController;
- (void)popToRootController;
- (void)presentControllerWithName:(NSString *)name context:(id)context;
- (void)presentControllerWithNames:(NSArray *)names contexts:(NSArray *)contexts;
- (void)dismissController;
- (void)becomeCurrentPage;
【注】
(a)push和present方法第一个参数对应的时Storyboard中设置的identifier字符串,watch kit extension 用这几个API向watch os传递消息,真实的UI加载渲染是在watch端进行
(b)popToRoot 是跳转到storyboard中main Entry Point 对应的Controller
(c)presentControllerWithNames 我们可以present一组Controller,这一组Controller将以page control的形式展示
(d)becomeCurrentPage当前页面是以page control 的形式展示的时候,调用这个方法可以改变当前的page
第二组
- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier;
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier;
- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex;
- (NSArray *)contextsForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex;
【注】可以直接在storyboard中设置TriggeredSegues,使用Segues时,同样支持push和model两种跳转方式
响应交互事件
WKInterfaceObject中像Button,Slider,Switch等控件可以和用户进行交互
【需要注意的是】
WKInterfaceController包含WkInterfaceTable实例时,可以通过实现默认的
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex
响应table每一行的点击事件,比UITableView更加简单
Glance (对用户进行短时的提醒)
可以通过storyboard创建一个Glance interface Controller对应到watchKit Extension中,同意继承于WKInterfaceController,享有同样的生命周期,也可以和用户进行交互
当用户Tap Glance 页面时,会跳转到我们的watch App中
//使用自定义的GlanceInterfaceController传递数据
- (void)updateUserActivity:(NSString *)type userInfo:(NSDictionary *)userInfo//比如我们需要点击Glance之后进入到某一个特定的页面,可以把目标页面的id和要传递的其他消息包装到字典中,然后在initial Interface Controller中实现 下面的方法
- (NSString *)actionForUserActivity:(NSDictionary *)userActivity context:(id *)context//跳转到目标页面,这里的userActivity就是上面传递的userInfo,返回的NSString是目标页面的identifier,context是目标页面的context
Notification&WKUserNotificationInterfaceController
//主体App支持Notification时,watch能够显示通知,当用户点击通知进入App时
- (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)remoteNotification
或者
- (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)localNotification//方法将会被响应,可以实现这两个方法获得通知的消息,跳转到目标页面
//可以通过storyboard创建一个Notifier interinterface Controller,可以实现自定义的通知界面
- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void(^)(WKUserNotificationInterfaceType interface)) completionHandler
或者
- (void)didReceiveLocalNotification:(UILocalNotification *)localNotification withCompletion:(void(^)(WKUserNotificationInterfaceType interface)) completionHandler//获得通知内容,并设置处理完成的回调block
Menu
//在上下文环境中添加相应的item
- (void)addMenuItemWithImage:(UIImage *)image title:(NSString *)title action:(SEL)action;
- (void)addMenuItemWithImageNamed:(NSString *)imageName title:(NSString *)title action:(SEL)action;
- (void)addMenuItemWithItemIcon:(WKMenuItemIcon)itemIcon title:(NSString *)title action:(SEL)action;
- (void)clearAllMenuItems;
WKInterfaceObject
负责界面的元素,只负责在WatchKit Extension 和 Watch App中传递响应的事件,具体的UI渲染在Watch App 中完成
Watch App 和 iOS App的布局方式完全不同,无法指定某个视图的具体坐标,不能用autolayout,只能以行为基本单位进行布局,如果一行中要显示多个元素,通过WKInterfaceGroup布局
WKInterfaceTable
可以通过storyboard直接在Controller中添加一个Table,每一个table默认包含一个Table Row Controller(继承的是NSObject),这个table row 相当于之前的cell,可以使用每一种row的样式,设置identifier来区分
//可以通过以下两组设置table的每一行的样式,rowType对应的时row Controller的identifier
- (void)setRowTypes:(NSArray *)rowTypes;
- (void)setNumberOfRows:(NSInteger)numberOfRows withRowType:(NSString *)rowType;
//可以通过- (id)rowControllerAtIndex:(NSInteger)index获得某一行对应的Row Controller
【例】
- (void)loadTableRows {
[self.interfaceTable setNumberOfRows:self.elementsList.count withRowType:@"default"];
// Create all of the table rows.
[self.elementsList enumerateObjectsUsingBlock:^(NSDictionary *rowData, NSUInteger idx, BOOL *stop) {
AAPLElementRowController *elementRow = [self.interfaceTable rowControllerAtIndex:idx];
[elementRow.elementLabel setText:rowData[@"label"]];
}];
}
//删除table的row
- (void)insertRowsAtIndexes:(NSIndexSet *)rows withRowType:(NSString *)rowType;
- (void)removeRowsAtIndexes:(NSIndexSet *)rows;
WKInterfaceDevice
这是一个单例类,可以获得当前的Watch的部分信息
@property(nonatomic,readonly) CGRect screenBounds;
@property(nonatomic,readonly) CGFloat screenScale;
@property(nonatomic,readonly,strong) NSLocale *currentLocale;
@property(nonatomic,readonly,copy) NSString *preferredContentSizeCategory;
另外我们可以使用这个类中的以下一组方法来缓存图片,以备将来继续使用:
- (void)addCachedImage:(UIImage *)image name:(NSString *)name;
- (void)addCachedImageWithData:(NSData *)imageData name:(NSString *)name;
- (void)removeCachedImageWithName:(NSString *)name;
- (void)removeAllCachedImages;
WKInterfaceImage
已经缓存的图片,可以使用下面的API直接读取:
- (void)setImageData:(NSData *)imageData;
- (void)setImageNamed:(NSString *)imageName;
WatchKit允许每一个App最多缓存20MB的图片,如果超过的话,WatchKit将从最老的数据开始删除,为新数据腾出空间。