原文链接:http://nshipster.com/watchkit/

前言

Watch的出世让很多人都很激动,尤为程序猿。

最佳起航途径是什么呢?毫无疑问那就是官方说明Apple's WatchKit developer resources

(吐槽略。。。)
本期为iOS开发者带来WatchKit的初体验。

正文

吐槽WatchKit正如当初的iPhoneOS(iOS)一样破土重生(吐槽略。。)

吐槽最后肯定了:

WatchKit is something to be enjoyed and celebrated.

对比UIKit(真正得正文)

WatchKit身上有UIKit深深的烙印,鉴于他们有着一样的历史跟愿景的情况下这一点都不奇怪。
手表跟电话还有平板不同,不同点在它们的展示桌面。有些概念是一样的,但是它们形状的限制刻画出了它们的软件。

为了对比,这里以UIKit / Cocoa里的概念形式映射到WatchKit的对应形式以便了解:

WatchKit(UIKit)
WKInterfaceController(UIViewController)
WKUserNotificationInterfaceController(UIApplicationDelegate + UIAlertController)
WKInterfaceDevice(UIDevice)
WKInterfaceObject(UIView)
WKInterfaceButton(UIButton)
WKInterfaceDate(UILabel + NSDateFormatter)
WKInterfaceGroup(UIScrollView)
WKInterfaceImage(UIImageView)
WKInterfaceLabel(UILabel)
WKInterfaceMap(MKMapView)
WKInterfaceSeparator(UITableView.separatorColor / .separatorStyle)
WKInterfaceSlider(UIStepper + UISlider)
WKInterfaceSwitch(WKInterfaceSwitch)
WKInterfaceTable(UITableView)
WKInterfaceTimer(UILabel + NSDateFormatter + NSTimer)

以上有许多重叠,但是这些有一些比较重要的区别。知道这些区别在写出一个很棒的WatchKit应用来说能提供很有用的信息的同时能启迪你苹果如果考虑设计API和(这方面)不断进步的最佳实践。

WKInterfaceController

WKInterfaceController负责管理场景中的所有元素,尽管UIViewController只是负责管理视图还有视图的子视图。接口对象不是视图,但是实际上它们扮演着同样的角色。

WKInterfaceController的指定构造器是initWithContext:,其带一个可选参数context对象:

override init(context: AnyObject?) {
    super.init(context: context)

    // ...
}

这里上下文又是什么(context)?其实你想让它是什么它就是什么:日期,字符串,数据模型或者什么都不是。

开放式的上下文参数可能会让你犯迷糊,但是它确是一个很聪明且值得称道的针对UIKit中长期存在的名字命名--不同的视图控制器之间的数据传递参数名字的解决方案。(开始吐槽。。略)

不好意思我离题了。(⊙﹏⊙b汗)

总的来说,WKInterfaceController的API还算干净,整个生命周期的方法阐述简直棒极:

// MARK: - WKInterfaceController

override func willActivate() {
    // ...
}

override func didDeactivate() {
    // ...
}

简单明了:就两个方法。没有加载中/卸载中,没有将要/已经出现/消失,没有animated:YES。(吐槽。。)苹果表应用简单性是必须的。iOS设备驱动程序与苹果表之间的通信属于费时费电的,所以所有的控制器接口场景设定将在构造器初始化以及willActivate后完成。在didDeactivate之间以及之后,苹果表将忽略尝试更新接口元素状态的动作。

苹果表应用是分层次者页面化的。这与Xcode的主次应用模板,页面应用模板和标签应用模板相似,所不同的是设计的选择是相互排斥的。

分层次应用有一个隐藏的导航栏栈,WKInterfaceController可以通过-pushControllerWithName:context:或者-popController进行管理。这里需要注意的一点是-pushControllerWithName:context:如何带一个字符串--故事板中特定的视图控制器的名字--而不是试图控制器本身这个实例。

另一方面,页面化应用扮演角色类似水平或者竖直的分页的滚动视图,带一个预定数字的场景都有一个控制器进行管理。看看这些有趣的栗子,主要是用了页面与层级的接口。无需真实设备下跑应用,。。。续

附带地,这里有一个有趣的苹果Swift示例代码,使用内部的结构体作为故事板常量名字空间:

class WatchListsInterfaceController: WKInterfaceController, ListsControllerDelegate {
    struct WatchStoryboard {
        static let interfaceControllerName = "WatchListsInterfaceController"

        struct RowTypes {
            static let list = "WatchListsInterfaceControllerListRowType"
            static let noLists = "WatchListsInterfaceControllerNoListsRowType"
        }

        struct Segues {
            static let listSelection = "WatchListsInterfaceControllerListSelectionSegue"
        }
    }

    // ...
}

WKInterfaceObject

WKInterfaceObject更像是重定义UIView的流水线,自带属性:alpha, hidden, horizontal & vertical alignment, and width & height.

最大的区别莫过于没有frame的定义。取而代之的是指定坐标点亦或是设定自动排版约束,WatchKit接口对象根据它们的边缘和各自的相对顺序,让人不经想起CSS类似Bootstrap的框架。

与Cocoa Touch中背离的一点是“目标-对象”的模式使用了针对每个控件进行定制的方式,而不再是传第一个动态的senderUIEvent

Object Action Method
Button - (IBAction)doButtonAction
Switch - (IBAction)doSwitchAction:(BOOL)on
Slider - (IBAction)doSliderAction:(float)value
Table - (IBAction)doTableRowTapAction:(NSInteger)rowIndex
Menu Item - (IBAction)doMenuItemAction

对小集合的控件套装,这样的处理方式还是很赞的。

WKInterfaceButton

WKInterfaceButton这个接口对象在点击的时候可以触发一个动作。它得内容可以是文本label或是一组(XO)。

组这个解决了添加子视图以及位置感精读的问题。用户体验会略好。

WKInterfaceTable

在所有从iOS转接过来的概念中,表格大概是改变最多的。

UITableView可以说是iPhone应用的脊柱。即便是这样,它们不断要随着要解决应用中诸多数据被以不同方式展示的需求来随之演变得更加复杂。WKInterfaceTable对比后看上去就不合主流了。

WatchKit表格没有sections or headers, or footers, or editing, or searching, or data sources, or delegates这些东西。

后者包含的东西 (续。。。)


Cruise_Chan
729 声望71 粉丝

技能树点歪了...咋办


引用和评论

0 条评论