3D Touch介绍: 一个数字压力器App和Quick Actions
2016-02-04 17:25
435 查看
随着iPhone 6s and 6s Plus的发布,苹果介绍了全新的手机交互方式:重按手势。你应该知道,这个特性其实早已应用在苹果手表和MacBook产品中,名字叫Force Touch。它给用户交互添加了全新的维度!
或许你对Force Touch为什么被重命名为3D touch感到奇怪。在克雷格·费德里吉(CraigFederighi,苹果工程师、高级副总裁)介绍这个新事物时(他自己也为名字感到困惑),大家就热烈讨论起来了。Force Touch这个名字有什么问题呢?太多星球大战的梗?
但是它们之间其实是有区别的!3D Touch能感应压力的大小,而Force Touch只可以检测到发生了重按。
虽然这个改变看起来并不十分重要,它允许开发者获得按压iPhone的压力明确值。这个实例app叫做
Gravity ,使得你的iPhone变为一个可以显示数字等级的Force Touch.虽然由于不明原因,苹果拒绝这样做,但是这个想法是有趣的,演示了3D Touch是如何工作的,让我们开始这个app吧!
![](https://img-blog.csdn.net/20160204165038043)
我们设计的app十分简单:一个包含两个label的view controller,其中一个是标题,另一个显示iPhone的压力百分比。
我们开始编码吧!在iPhone 6s 和 6s Plus,UITouch对象有两个CGFloat类型的属性,分别是force和maximumPossibleForce。force代表触摸的压力的大小,1.0表示正常的触摸。MaximumPossibleForce表示一次触摸的最大压力。
当用户触摸屏幕,touchesBegan会被调用,然后是touchesMoved(如果用户在屏幕上移动它的手指),再然后就要根据实际情况,可能是touchedCancelled或者TouchesEnded被调用。根据我们的需求,只有touchesMoved方法才是我们需要的。TouchesMoved有两个参数:touches和event。touches是一个存储了UITouch对象的Set对象(无顺序集合),touches中至少含有一个UITouch对象,但是谨慎起见,强烈建议先判断
touches.first是否为nil,在ViewController.swift中插入下面的方法:
在if子句中,我们先判断设备是否支持3D Touch。如果你只是凭兴趣玩一下,这部分是可选的。如果你要将app发布到AppStore,一定要执行判断,因为iPhone6等老设备是不支持3D Touch的。
注意我同时检测了设备是否在iOS9.0及更新的版本中运行。我使用了Swift2.0的#available语句。如果你想进一步学习Swift 2.0的新特性,我建议你阅读这篇博客。如果你项目的deployment target是9.0或者以上版本,版本检测也是可选的。
为了获得压力百分比,只需要简单地将压力除以可能达到的最大压力(touch.maximumPossibleForce),然后更新label的文字:
如果你在iPhone 6s/6s Plus上运行项目,当你按压屏幕时,会显示压力百分比。然而你可能希望以“克”为单位来显示。根据Ryan
McLeod的测试,感器的计量范围的最大值是 385g(约等于3.8牛)。通过简单的计算,你可以将 %压力转化为克。我们只需要将压力百分比乘以385。对于超过385的数据,我们只要改变label的文字,告诉用户:“385+ 克”。
现在,更新代码片段:
太酷了!你已经完成了一个数字压力app。
![](https://img-blog.csdn.net/20160204165518691)
现在,当手指移开屏幕后,app并没有复位,你可以实现touchesEnded方法来将label复位。
![](https://img-blog.csdn.net/20160204165652129)
我们就为我们的app添加Quick Action,来以蓝色的背景打开它而不是现在的白色。为了添加Quick Actions,打开项目的info.plist 文件。在文件中,添加一个’UIApplicationShortcutItems’数组。数组的每一个元素都是一个dictionary,而dictionary包含一个Quick Action的一些属性:
•
UIApplicationShortcutItemType(必须)一个标识Quick Action的字符串。注意这个字符串必须是唯一的。建议使用bundle ID或者其它app唯一字符串作为前缀。
•
UIApplicationShortcutItemTitle (必须)显示给用户看的Quick Action的标题。例如:“最新照片”。
•
UIApplicationShortcutItemSubtitle (可选)显示在标题底下的文字。例如:“昨天最新的照片”。如果你想在Quick Action中添加图片,有两种可能性:系统图标、用户自定义图标。
•
UIApplicationShortcutItemIconType (可选) 你希望在 Quick Action中显示的系统图标的字符串
•
UIApplicationShortcutItemIconFile (可选) 你希望在 Quick Action中显示的自定义图标的字符串
•
UIApplicationShortcutItemUserInfo (可选) 包含一些你想传递的额外的信息的字典。
在这个数组中,我们定义了4个属性来配置 “OpenBlue” Quick Action。你的 info.plist应该是这样子的:
![](https://img-blog.csdn.net/20160204165723068)
说明一下,我使用’$(PRODUCT_BUNDLE_IDENTIFIER)’而不是 ‘com.appcoda.Scale’或者其它bundle ID,是为了安全着想:如果我将Bundle ID改为’General’,会影响整个项目,每个用到Bundle ID的地方都需要修改。在info.plist文件中,你会发现Bundle Identifier key也是使用‘$(PRODUCT_BUNDLE_IDENTIFIER)’来描述项目的Bundle ID。
最后需要做的是,当用户启动时,实现Quick action。在AppDelegate.swift中的performActionForShortcutItem方法中处理快捷事件。当触发了Quick Action,这个方法会被调用。所以需要在此方法中处理快捷事件。
你需要根据quick action的成功或失败,调用completionHandler,并且传递一个布尔值。这里我们创建一个单独的函数handleQuickAction来处理快捷事件。推荐使用UIApplicationShortcutItemType枚举,来表示 Quick Action的事件。像下面这样声明枚举并且实现handleQuickAction方法:
这一切都十分简单。如果你现在quick actions使用运行app,它的背景是蓝色的!
![](https://img-blog.csdn.net/20160204170109193)
![](https://img-blog.csdn.net/20160204170133448)
在didFinishLaunchingWithOptions方法中,我们有一行代码来设置背景色为白色。在直接点击图标启动app时,这行代码会被执行。
这就是问题所在:当你通过quick action启动时,willFinish,didFinish,然后是performActionForShortcutItem会被执行,所以背景是由白色变为蓝色。很明显,你并不希望在通过快捷启动app启动时,将背景设为白色。
为了解决这个问题,我们需要在didFinishLaunchingWithOptions方法中执行判断:
你可以通过UIApplicationLaunchOptionsShortcutItemKey来确定app是否是通过快速启动打开的,然后决定是否调用handleQuickAction来改变背景颜色。
因为我们已经在didFinishLaunchingWithOptions中处理快捷启动,我们不需要再调用performActionForShortcutItem来处理。所以,最后我们返回一个false值,告诉系统不需要执行performActionForShortcutItem方法。
你可以测试你的app了,快捷启动应该可以完美运行!
Conclusion
3D Touch是一个好用且有意思的功能,但你需要知道,还不是所有设备都支持3D Touch。
你阅读完这篇博文后,你应该能在你的app中添加Quick Actions,知道怎么检测按压力度了。你可以下载完整的源码作为参考。(晚点上传Objective-c版本)
原文:http://www.appcoda.com/3d-touch-tutorial/
或许你对Force Touch为什么被重命名为3D touch感到奇怪。在克雷格·费德里吉(CraigFederighi,苹果工程师、高级副总裁)介绍这个新事物时(他自己也为名字感到困惑),大家就热烈讨论起来了。Force Touch这个名字有什么问题呢?太多星球大战的梗?
但是它们之间其实是有区别的!3D Touch能感应压力的大小,而Force Touch只可以检测到发生了重按。
虽然这个改变看起来并不十分重要,它允许开发者获得按压iPhone的压力明确值。这个实例app叫做
Gravity ,使得你的iPhone变为一个可以显示数字等级的Force Touch.虽然由于不明原因,苹果拒绝这样做,但是这个想法是有趣的,演示了3D Touch是如何工作的,让我们开始这个app吧!
Let’s Get Started
首先,我们下载项目的模板。基本上,这只是一个空的 Single View iPhone应用。我创建了app的界面(UILabels 和 a UIImage),并且连接了IBOutlets到ViewController.swift中。我们设计的app十分简单:一个包含两个label的view controller,其中一个是标题,另一个显示iPhone的压力百分比。
我们开始编码吧!在iPhone 6s 和 6s Plus,UITouch对象有两个CGFloat类型的属性,分别是force和maximumPossibleForce。force代表触摸的压力的大小,1.0表示正常的触摸。MaximumPossibleForce表示一次触摸的最大压力。
当用户触摸屏幕,touchesBegan会被调用,然后是touchesMoved(如果用户在屏幕上移动它的手指),再然后就要根据实际情况,可能是touchedCancelled或者TouchesEnded被调用。根据我们的需求,只有touchesMoved方法才是我们需要的。TouchesMoved有两个参数:touches和event。touches是一个存储了UITouch对象的Set对象(无顺序集合),touches中至少含有一个UITouch对象,但是谨慎起见,强烈建议先判断
touches.first是否为nil,在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发布到AppStore,一定要执行判断,因为iPhone6等老设备是不支持3D Touch的。
注意我同时检测了设备是否在iOS9.0及更新的版本中运行。我使用了Swift2.0的#available语句。如果你想进一步学习Swift 2.0的新特性,我建议你阅读这篇博客。如果你项目的deployment target是9.0或者以上版本,版本检测也是可选的。
为了获得压力百分比,只需要简单地将压力除以可能达到的最大压力(touch.maximumPossibleForce),然后更新label的文字:
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" } } } }
如果你在iPhone 6s/6s Plus上运行项目,当你按压屏幕时,会显示压力百分比。然而你可能希望以“克”为单位来显示。根据Ryan
McLeod的测试,感器的计量范围的最大值是 385g(约等于3.8牛)。通过简单的计算,你可以将 %压力转化为克。我们只需要将压力百分比乘以385。对于超过385的数据,我们只要改变label的文字,告诉用户:“385+ 克”。
现在,更新代码片段:
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 = Int(grams) forceLabel.text = "\(roundGrams) grams" } } } } }
太酷了!你已经完成了一个数字压力app。
现在,当手指移开屏幕后,app并没有复位,你可以实现touchesEnded方法来将label复位。
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { forceLabel.text = "0 gram" }
Home Screen Quick Actions
3D Touch的另一个用法是在Home页的Quick Actions(快速操作)。Quick actions 是用户直接跳转到app某些页面的一个快捷方式。简单地重压app的图标,你可以看见一个快捷菜单。在3D Touch的介绍文档,展示了Twitter 、Instagram,以及一些其它苹果app使用了这一特性。我们就为我们的app添加Quick Action,来以蓝色的背景打开它而不是现在的白色。为了添加Quick Actions,打开项目的info.plist 文件。在文件中,添加一个’UIApplicationShortcutItems’数组。数组的每一个元素都是一个dictionary,而dictionary包含一个Quick Action的一些属性:
•
UIApplicationShortcutItemType(必须)一个标识Quick Action的字符串。注意这个字符串必须是唯一的。建议使用bundle ID或者其它app唯一字符串作为前缀。
•
UIApplicationShortcutItemTitle (必须)显示给用户看的Quick Action的标题。例如:“最新照片”。
•
UIApplicationShortcutItemSubtitle (可选)显示在标题底下的文字。例如:“昨天最新的照片”。如果你想在Quick Action中添加图片,有两种可能性:系统图标、用户自定义图标。
•
UIApplicationShortcutItemIconType (可选) 你希望在 Quick Action中显示的系统图标的字符串
•
UIApplicationShortcutItemIconFile (可选) 你希望在 Quick Action中显示的自定义图标的字符串
•
UIApplicationShortcutItemUserInfo (可选) 包含一些你想传递的额外的信息的字典。
在这个数组中,我们定义了4个属性来配置 “OpenBlue” Quick Action。你的 info.plist应该是这样子的:
说明一下,我使用’$(PRODUCT_BUNDLE_IDENTIFIER)’而不是 ‘com.appcoda.Scale’或者其它bundle ID,是为了安全着想:如果我将Bundle ID改为’General’,会影响整个项目,每个用到Bundle ID的地方都需要修改。在info.plist文件中,你会发现Bundle Identifier key也是使用‘$(PRODUCT_BUNDLE_IDENTIFIER)’来描述项目的Bundle ID。
最后需要做的是,当用户启动时,实现Quick action。在AppDelegate.swift中的performActionForShortcutItem方法中处理快捷事件。当触发了Quick Action,这个方法会被调用。所以需要在此方法中处理快捷事件。
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) { // Handle quick actions completionHandler(handleQuickAction(shortcutItem)) }
你需要根据quick action的成功或失败,调用completionHandler,并且传递一个布尔值。这里我们创建一个单独的函数handleQuickAction来处理快捷事件。推荐使用UIApplicationShortcutItemType枚举,来表示 Quick Action的事件。像下面这样声明枚举并且实现handleQuickAction方法:
enum Shortcut: String { case openBlue = "OpenBlue" } func handleQuickAction(shortcutItem: UIApplicationShortcutItem) -> Bool { var quickActionHandled = false let type = shortcutItem.type.componentsSeparatedByString(".").last! if let shortcutType = Shortcut.init(rawValue: type) { switch shortcutType { case .openBlue: self.window?.backgroundColor = UIColor(red: 151.0/255.0, green: 187.0/255.0, blue: 255.0/255.0, alpha: 1.0) quickActionHandled = true } } return quickActionHandled }
这一切都十分简单。如果你现在quick actions使用运行app,它的背景是蓝色的!
One Thing to Keep in Mind
但是你还需要记住一件事,使用Quick Action正常启动app和从后台打开是有区别的。当一个app正常启动willFinishLaunchingWithOptions和didFinishLaunchingWithOptions方法会被调用,但从后台打开时,只会执行performActionForShortcutItem方法。在didFinishLaunchingWithOptions方法中,我们有一行代码来设置背景色为白色。在直接点击图标启动app时,这行代码会被执行。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. self.window?.backgroundColor = UIColor.whiteColor() return true }
这就是问题所在:当你通过quick action启动时,willFinish,didFinish,然后是performActionForShortcutItem会被执行,所以背景是由白色变为蓝色。很明显,你并不希望在通过快捷启动app启动时,将背景设为白色。
为了解决这个问题,我们需要在didFinishLaunchingWithOptions方法中执行判断:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { print("didFinishLaunchingWithOptions called") var isLaunchedFromQuickAction = false // Check if it's launched from Quick Action if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem { isLaunchedFromQuickAction = true // Handle the sortcutItem handleQuickAction(shortcutItem) } else { self.window?.backgroundColor = UIColor.whiteColor() } // Return false if the app was launched from a shortcut, so performAction... will not be called. return !isLaunchedFromQuickAction }
你可以通过UIApplicationLaunchOptionsShortcutItemKey来确定app是否是通过快速启动打开的,然后决定是否调用handleQuickAction来改变背景颜色。
因为我们已经在didFinishLaunchingWithOptions中处理快捷启动,我们不需要再调用performActionForShortcutItem来处理。所以,最后我们返回一个false值,告诉系统不需要执行performActionForShortcutItem方法。
你可以测试你的app了,快捷启动应该可以完美运行!
Conclusion
3D Touch是一个好用且有意思的功能,但你需要知道,还不是所有设备都支持3D Touch。
你阅读完这篇博文后,你应该能在你的app中添加Quick Actions,知道怎么检测按压力度了。你可以下载完整的源码作为参考。(晚点上传Objective-c版本)
原文:http://www.appcoda.com/3d-touch-tutorial/
相关文章推荐
- Android的Touch事件处理机制介绍
- mysql压力测试脚本实例
- js的touch事件的实际引用
- Android Touch事件分发过程详解
- Sench Touch 监听滚动事件
- Secnha Commands 3 使用详解(从创建到打包)
- sencha touch 彩色图标按钮(button+ico)
- 指尖下的js ——多触式web前端开发之一:对于Touch的处理
- Android 编程下 Touch 事件的分发和消费机制
- 80后全球速写:生存压力成最大现实考验
- Linux下查看 && 修改文件的时间属性
- linux 命令-- touch
- 随记:关于linux setUID
- 网游《Gogoxing》开始韩国压力测试
- 《起源》人气狂飙升 压力测试爆服!
- iPhone 4S
- shell命令find删除修改后带尾巴的重复的文件
- shell命令find删除修改后带尾巴的重复的文件
- shell chown改变文件属主命令
- WIN和linux下文件名长度限制