数码表冠
数码表冠(Digital Crown)是 Apple Watch 的主要硬件输入,让人们能够翻滚屏幕内容、切换到不同的应用程序以及运用 Siri。
咱们将了解在开发中,怎么操控数码表冠。
需要留意的点
developer.apple.com/design/huma…
依据 Apple Human Interface Guidelines,咱们测验为 watchOS App 增加与数码表冠的交互时,需要留意:
-
供给视觉反应以响应数码表的交互。例如,当用户运用 Digital Crown 时,挑选器会更改当时显示的值。假如开发中盯梢数码表的旋转,请运用接收到的旋转数据来更新 App 的界面。假如开发中不供给视觉反应,用户可能会以为旋转数码表对 App 有任何影响。
-
以数码表旋转相对应的速度更新界面。数字表冠的旋转应该让用户对界面进行准确操控。考虑运用旋转速度来确认进行更改的速度。避免用户难以舒适的更新内容。
-
在 App 中运用默许的触觉反应。例如能够调整表格视图的触觉反应行为,让它们运用线性定位而不是基于行的定位,给用户带来更共同的体会。
Swift & SwiftUI
数码表冠绑定数字
构建项目
咱们创立一个独立的 watchOS App 项目 DigitalCrownDemo
。并将 Interface
挑选为 SwiftUI
。
调整 ContentView.swift
代码,以展现当时数字:
struct ContentView: View {
@State var number: Float = 0
var body: some View {
Text("\(number, specifier: "%.1f")")
}
}
与数码表冠绑定
调整代码:
Text("\(number, specifier: "%.1f")")
.focusable()
.digitalCrownRotation($number)
默许情况下,Text 不会承受焦点,由于它不是交互式元素。 运用 digitalCrownRotation
修饰符时,需要在调用之前立即运用 .focusable()
。
digitalCrownRotation
一直将绑定作为任何实现 BinaryFloatingPoint
协议的第一个参数,例如 Float、Double。
构建并运转项目。 这一次,当咱们翻滚数字表冠时,咱们会看到数字发生了改变。
约束翻滚规模
通常上述的体现不是咱们期望的。咱们更多的是给定一个可操作的规模。请持续调整代码:
.digitalCrownRotation($number, from: 0.0, through: 10.0)
咱们增加了数码表冠的翻滚约束,从 0.0 ~ 10.0,构建并运转项目,咱们会发现实际情况有些不符合预期:
咱们发现翻滚会显示下限值 -0.1 和上限值 10.1。 咱们有必要再增加一个参数来告诉数码表冠更改值的起伏。
.digitalCrownRotation($number, from: 0, through: 10, by: 0.1)
再次构建并运转项目。 这次咱们会得到预期的结果。
咱们深入看一下这里,持续调整代码,并翻滚数码表冠:
Text("\(number, specifier: "%.1f")")
.focusable()
.digitalCrownRotation($number, from: 0, through: 10, by: 0.1)
.onChange(of: number) { newValue in
print(newValue)
}
咱们会发现,绑定特点更新的值咱们幻想的要多得多。同时旋转停止时,绑定特点通常不受by:参数的约束。
假如咱们需要对浮点数执行相等性检查,请运用舍入办法,如下所示:
if (value * 100).rounded(.towardZero) / 100 == 9.75 {
...
}
developer.apple.com/documentati…
(5.2).rounded(.towardZero)// 5.0
(5.5).rounded(.towardZero)// 5.0
(-5.2).rounded(.towardZero) // -5.0
(-5.5).rounded(.towardZero)// -5.0
rounded(.towardZero)
向零舍入来将供给的值舍入为整数值。你乘以 10^X 并除以 10^X ,其间 X 是咱们要比较的小数位数。
如案例代码,9.75 有两位小数,咱们的 value 为 9.755,9.755 * 10^2 = 975.5 -> 975 -> 975 / 100 = 9.75,此刻,结果为 true。
灵敏度、循环与触觉反应
有时候,咱们需要调整数字表冠的灵敏度来使交互更加流通。持续调整代码:
构建并运转项目,能够将值从 .high 更改为 .medium 再更改为 .low 并进行体会。当值为 .low时,咱们有必要将数码表冠转动得更多。 这里的默许值为 .high。
关于数字规模停止是有意义的。 在其他情况下咱们可能期望值是循环的,用户能够正常翻滚到 10.0,但假如用户持续翻滚,该值将变为 0.0 并再次核算。 苹果称之为接连翻滚(Continuous scrolling)。 默以为 false:
Text("\(number, specifier: "%.1f")")
.focusable()
.digitalCrownRotation(
$number,
from: 0,
through: 10,
by: 0.1,
sensitivity: .low,
isContinuous: true
)
再次构建并运转。 接连翻滚数字表冠,你会看到数字能够进行循环。
默许情况下,翻滚数码表冠会向用户供给少量触觉反应。 假如对咱们的 App 没有意义,咱们能够运用 相关参数将其封闭:
.digitalCrownRotation(
$number,
from: 0,
through: 10,
by: 0.1,
sensitivity: .low,
isContinuous: true,
isHapticFeedbackEnabled: false
)
Swift & Storyboard
数码表冠绑定数字
咱们将测验运用 Storyboard 实现上述 Demo。首要创立项目,将 Interface
设置为 Storyboard
。
拖入 Lable 并进行样式的调整:
在 InterfaceController.swift
中,进行 numberLabel
text 的设置:
class InterfaceController: WKInterfaceController {
private var number = 0.0
@IBOutlet var numberLabel: WKInterfaceLabel!
override func awake(withContext context: Any?) {
// Configure interface objects here.
updateUI()
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
}
private func updateUI() {
numberLabel.setText(String(format: "%.1f", number))
}
}
向 InterfaceController
类增加代码,需要为 CrownSequencer
增加代理,并使他聚集:
override func didAppear() {
crownSequencer.delegate = self
crownSequencer.focus()
}
WKCrownSequencer
是报告数字表冠当时状态的目标,包含其运动时的旋转速度。咱们不要自己创立此类的实例,而是从当时 InterfaceController
的特点中检索一个表冠序列器目标。
在其能够接收数据之前,咱们有必要调用它的 focus()
办法。在任何给定时间,咱们的界面中只要一个目标能够具有焦点,因此假如咱们的界面还包含挑选器目标或具有可翻滚的场景,您有必要相应地协调焦点的改变。
由于表冠序列器不绑定到特定的界面目标,所以咱们能够将其用作应用程序的一般输入。
WKCrownSequencer
供给两个状态特点:
-
var rotationsPerSecond: Double表冠的旋转速度,以每秒转数为单位。转速是绝对值。不管旋转方向怎么,它一直为正。
-
var isIdle: Bool一个布尔值,指示表冠是否处于停止状态。
WKCrownSequencer
有一个触觉反应特点:
- var isHapticFeedbackEnabled: Bool { get set } 一个布尔值,用于确认是否启用数码表冠的触觉反应。
持续修改咱们的 InterfaceController
使其符合 WKCrownDelegate
协议。
extension InterfaceController : WKCrownDelegate {}
在 WKCrownDelegate
的 extension
增加代码:
func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
print(rotationalDelta)
}
func crownDidBecomeIdle(_ crownSequencer: WKCrownSequencer?) {
print("End")
}
-
crownDidRotate(rotationalDelta:)
当用户旋转数字表冠时调用。自前次更新以来表冠旋转的量。1.0 的值表明一整圈。值的符号表明旋转的方向,但符号会依据表冠的方向进行调整。正值一直表明向上翻滚手势,而负数表明向下翻滚手势。用户能够在手表的设置中更改数字表冠的方向。
developer.apple.com/documentati…
-
crownDidBecomeIdle()
当用户停止旋转表冠时调用。
developer.apple.com/documentati…
运转项目并查看输出。
调整代码,核算咱们当时需要展现的值:
func crownDidRotate(_ crownSequencer: WKCrownSequencer?, rotationalDelta: Double) {
number = number + rotationalDelta
if number < 0.0 { number = 10.0 }
if number > 10.0 { number = 0.0 }
updateUI()
}
运转项目,此刻咱们的数码表冠现已和数字绑定: