北京时间2015年12月4日,Swift开源,明年秋季发布Swift3.0版本。
然而我的App被拒了,哔了狗了。
谁想要请自行编译。
先去下载这个初始案例。初始案例中只有一个空的 Single View。我在里面创建了 App 必要的 UI 元素(UILabel和UIImage),并关联了ViewController.swift。
这个 App 的设计很简单:ViewController 上有两个 Label:一个标题和一个显示按压百分比的文本。
在 iPhone6s 和 6s Plus 上,UITouch对象多了两个CGFloat类型的属性,分别是force和maximumPossibleForce。force表示按得有多重,1.0表示常规状态的值。maximumPossibleForce表示能承受的最大压力值。
无论什么情况,当用户触摸屏幕时,touchesBegan方法会被调用,接着就是touchesMoved(如果用户手指在屏幕上滑动,那么touchedCancelled与TouchesEnded也会被调用)。在这个App中,我们只需要关注touchesMoved
方法。touchesMoved有两个参数:touches和event。
touches是一个装着UITouch对象的NSSet类型集合(集合无序,并且无重复)。我们必须要确保在touches中只有一个UITouch对象,但也有考虑不完全的时候,所以强烈建议大家先利用可选绑定来判断touches.first(touches
中的第一个UITouch对象)是否是空。
在ViewController.swift中添加以下:
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
if #available(iOS 9.0, *) {
if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {
// 3D Touch capable }
}
}
}
在这个if判断中,还需要添加判断当前设备是否支持 3D Touch。如果你只是做来玩,那就没必要验证。但是,如果是要上架的 App,那就必须要判断,毕竟像 iPhone6 这些旧设备不支持 3D Touch。
除此之外,我还使用了#available语句(Swift 2.0)对当前系统是否是 iOS9+ 做了判断。
同样,如果你的编译环境是 iOS9.0+,那么这个判断可以省略。
要得到按压百分比?只需要用force属性除以maximumPossibleForce就可以了(例如:touch.maximumPossibleForce),maximumPossibleForce
表示能承受的最大压力值。然后,更新文本:
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
if #available(iOS 9.0, *) {
if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {
// 3D Touch capable let force = touch.force/touch.maximumPossibleForce
forceLabel.text = "\\(force)% force"
}
}
}
}
如果你在 iPhone6s/6s Plus 上跑这个程序,按屏幕时就能看到压力百分比了。但是,其实我们更想知道放在 iPhone 上物体的重量,而不是百分比。根据�「线性代数」进行回归计算分析,可以知道,传感器的计量范围的最大值是 385g。
因此,maximumPossibleForce就相当于 385g(相当于3.8N)。通过简单的计算,就可以把压力百分比转为克。需要做的仅仅是用百分比*385。对于重于 385g 的物体,就把 label 改成类似于“385+ grams”这样的文本好了。
到此,touchesMoved方法更新为:
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
if #available(iOS 9.0, *) {
if traitCollection.forceTouchCapability == UIForceTouchCapability.Available {
if touch.force >= touch.maximumPossibleForce {
forceLabel.text = "385+ grams"
} else {
let force = touch.force/touch.maximumPossibleForce
let grams = force * 385
let roundGrams = Float(grams)
forceLabel.text = "\\(roundGrams) grams"
}
}
}
}
}
还有一个小问题:当物体或者触摸事件结束之后,文本没有重置。你可以实现touchesEnded
方法来达到效果:
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
forceLabel.text = "0 gram"
}