WatchKit by tutorials 笔记(一)

四月底把 Ray 家的 WatchKit by tutorials 刷了一遍,总体难度不大,毕竟是初代产品,这里大概挑重点总结一下。同样的如果你对本书感兴趣,请购买英文正版。

#Section I: Beginning WatchKit

Chapter 1: Hello, Apple Watch

这一章主要讲如何创建一个 Apple Watch App,步骤如下:

  • 添加一个 Watch app target 到工程中去,添加完成后 project navigator 中会出现一个 WatchKit Extension group 和一个 WatchKit App group.
  • 打开 WatchKit AppInterface.storyboard 设置 Attributes Inspector
  • 将 scheme 设置为 HelloAppleWatch Watch App,Run~

Chapter 2: Architecture

  1. WatchKit 的交互主要有四种方式
    • Action-based events:类似与 table row selection 和 tap-base UI controls
    • Gestures:仅仅支持水平和垂直 swipes 手势和 taps 手势,不支持多点触控
    • Force touch:Watch 的屏幕周围有一圈细小的电极,用来判断是重按还是轻按,这个手势用来弥补多点触控
    • The digital crown:使用数字表冠进行 view 的滚动操作
  2. Watch 的显示规格
    • 38mm Watch 宽272 X 高340
    • 42mm Watch 宽312 X 高390
  3. WatchKit 简介,其实就是一些类和 IB 的集合,包含一些重要的类如下:
    • WKInterfaceController,WatchKit 版本的 UIViewController
    • WKInterfaceObject,表示 Watch Interface 的一些最基本的元素,如 button,labels 等
    • WKInterfaceDevice,关于 Watch 的一些信息,如屏幕尺寸,位置等
  4. Watch APP 只负责显示,真正的代码执行是在 iPhone 上,即 WatchKit extension 来执行代码,虽然 WatchKit extension 和 container app 同在 iPhone 上,但他们独立运行在各自的沙盒之中,相互不能直接访问,他们之间的交流是通过 Share App Group 来实现的。
    Watch App 上只存放 watch 相关的本地资源和图片,从网上下载资源也是先下载到 iPhone 上,再传输到 watch 上。你不能手动控制向 Watch 传送资源,这一切都是自动的。

  5. WatchKit Class

    WKInterfaceController 的生命周期

    • awakeWithContext(_:) controller 从 IB 中载入后会立即调用
    • willActivate() 准备显示
    • didDeactivate() 准备离开屏幕时调用,这里可以做些清理工作

    Segues 管理着两个 WKInterfaceController 切换时的一些工作

    • contextForSegueWithIdentifier( _:) 返回一个 AnyObject,在第一个 VC 中调用传递
    • awakeWithContext( _:) 在第二个 VC 中 调用接受传递来的 AnyObject
  6. Interface objects
    总共有 11 种基本界面元素,这些 Watch App Interface objects 继承自 WKInterfaceObjects,由于真正的代码是由 WatchKit extension 在 iPhone 上执行,并将执行的结果 UI State 打包传送给 Watch 来显示。这些 Interface objects 可以看做是 Watch 上视觉元素的代理对象,他们也继承来了一些便利的方法:

    • setHidden(_:)
    • setAlpha(_:)
    • setWidth(_:)setHeight(_:)
    • setAccessibilityLabel(_:)setAccessibilityHint(_:)setAccessibilityValue(_:)

    因为是代理对象,所以没有 getter ,全是 setter

    十一个基本界面元素:

    • WKInterfaceButton
    • WKInterfaceDate
    • WKInterfaceGroup
    • WKInterfaceImage
    • WKInterfaceLabel
    • WKInterfaceMap
    • WKInterfaceSeparator
    • WKInterfaceSlider
    • WKInterfaceSwitch
    • WKInterfaceTable
    • WKInterfaceTimer
  7. Layout WatchKit 的 layout 类似于 HTML 和 CSS layout,基于内容自动布局。

  8. Animations WatchKit 的动画是由多张图片组成的,类似与 GIF
  9. Notifications 通知

    • short look 只能看到 app 的一些 icon,标题之类的
    • long look 分为静态 static 和动态 dynamic 通知。静态通知必须给 WatchKit extension 提供 image 资源;而动态通知,你可以自定义通知界面。

    可以为通知添加任意的 action ,如果一个 app 同时实现了两种类型的通知,那么在收到通知时,先振动并显现 short look,然后用户抬起手腕则切换到 long look。

  10. Glances 为你的 App 提供一个 quick look,有点类似于通知中心
    你可以在 glance 中使用 updateUserActivity(_:userInfo:) 来发布上下文信息(contextual information)让你的 Watch app 知道用户点击了 glance 所展示的哪个应用,在你的 APP 中的 initial interface controller 实现 handleUserActivity(_:) 来处理这一相关的 activity(用户点击)

Chapter 3: UI Controls

本章节主要熟悉 Interface objects 的使用以及 layout 的操作,在 WKInterfaceController 中完成这些 Interface objects 背后的逻辑计算。

Chapter 4: Layout

本章主要介绍 WatchKit 独特的 Layout 系统,最重要的三个特性就是:groups, content sizingrelative spacing

WatchKit 中的 Navigation 主要有以下三种形式

  • Hierarchical 类似于 UINavigationController
  • Page-based 类似于 UIPageViewController
  • Modal 任何类型的 presentation 和 dismissal

  • Hierarchical navigation

    可以通过在 IB 中 Control-drag 或在代码中调用 pushControllerWithName(_:context:) 来实现过渡

  • Page-based navigation

    这是一个拥有多个 WKInterfaceController 实例的组对象,你可以通过 swipe 手势来切换他们,这里注意的是你不能在同一个 Group 中的不同 controllers 之间传递 context ,也不能在这些 controllers 上使用 hierarchical navigation。

    但是你可以通过在 page-based navigation 上以模态的形式展示一个 hierarchical navigation

    你可以在 IB 上用 next page 将他们连接起来,也可以在 code 中实现:

    • becomeCurrentPage() 调用此方法使当前 interface controller 成为 page-based interface 的当前页
    • reloadRootControllersWithNames(_:contexts:) 调用此方法重新载入 page-based interface 中的 pages
  • Modal navigation
    可以通过在 IB 中 Control-drag 或在代码中调用

    • presentControllerWithName(_:context:) 模态显示单个
    • presentControllerWithNames(_:contexts:) 模态显示多个
    • dismissController()

Chapter 6: Tables

Watch 的 tables 和 iOS 的并没有什么大的区别,唯一不同的是 Watch 的 tables 没有 section,只能显示一维的数据,在 SB 中拖一个 table ,只需要设置:

table.setNumberOfRows(10, withRowType: "IngredientRow")  

这个 row type 类似于 UITableViewCell reuse identifier。

WatchKit 中,苹果介绍了一个新的类,叫做 Row controller,虽然叫做 controller,但他其实是 NSObject 的子类,作为一个容器,管理着一些显示在 row 上面的视觉元素。(有点类似与自定义的 UITableViewCell)

在 storyboard 上,你可以创建不同的 table rows,设置他们的类为自定义的 row controller,并给他们设置唯一的 identifier

WKInterfaceTable 的 row 没有默认的 row controller class,所以必须创建 Row controller 这个类

为什么一个没有 section 的一维结构的表要 identifiersrow controllers,因为,需要两种类型的 row,一个表示 header,另一个表示 row。

将数据源放在 Framework 中,这样 iPhone App 和 Watch App 都能够很方便的访问。

要理解 Menus,首先要了解一下 Apple 放出的一个新手势 force touch,把手指在屏幕上按住一会,如果当前上下文存在一个 menu,就会弹出一个 menu,下面是一些 Menu 的样式图:

38mm 和 42mm 的 Watches Menus 相关的尺寸也不一样

  • 对于 38mm,canvas(画布)尺寸 70 像素,内容尺寸 46 像素,保持元素间距 4 到 8 个像素
  • 对于 42mm,canvas(画布)尺寸 80 像素,内容尺寸 54 像素,保持元素间距 5 到 9 个像素

一般屏幕上只能容纳四个,Cancel 会预先占一个,Menu 界面不能滚动,也不能添加其他的 interface objects

Menu 上的 menu items Action 实现起来也非常简单,不需要遵守什么 protocol,只要将 IB 上的这些 menu items 和 code 中的 action func 通过 Control + drag 连接起来,也就是我们熟悉的 target-action 模式。


-EOF-

如果感觉此文对你有帮助,请随意打赏支持作者 😘

chengway

认清生活真相之后依然热爱它!

Subscribe to Talk is cheap, Show me the world!

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!