3D Touch介绍:电子秤App与快捷操作

随着iPhone6s与6s plus的到来,苹果给我们展现了一种全新的交互方式:重按手势。你可能知道,这个特性已经在Apple Watch和MacBook上推出了,不过那时叫Force Touch,就是字面上的意思,给用户的交互添加一种新的维度。

如果你很好奇iPhone的Force Touch为啥要更名为3D Touch,那告诉你吧,you’re not alone(译者注:请用MJ的调子唱出来…)。不久前,之前也对这名字纠结不已的Craig Federighi(译者注:Apple高级副总裁)介绍了这个新特性,第一条微博就这样产生了。也不知道Force Touch这名字有啥不好的,就因为有太多星球大战的梗?(译者注:其实我不知道这梗…)

但是,Force Touch和3d Touch确实不一样!Force Touch只能识别重按。这方面3D Touch要灵敏多了,它能够识别按压的力度。

虽然说,这点不同看起来无足轻重,但是这使开发者能开发更多精确计量方面的App。比如这一款名为Gravity的应用,它利用Force Touch让你的iPhone成为了一个电子秤。虽然这款App被Apple拒了,但是这创意简直太棒了。所以,为了展示3D Touch的工作流程,我们来做一个简单的App。

先去下载这个初始案例。初始案例中只有一个空的Single View。我在里面创建了App必要的UI元素(UILabelUIImage),并关联了ViewController.swift

这个App的设计很简单:ViewController上有两个Label:一个标题和一个显示按压百分比的文本。

那…开始写代码吧!在iPhone6s和6s Plus上,UITouch对象多了两个CGFloat类型的属性,分别是forcemaximumPossibleForceforce表示按得有多重,1.0表示常规状态的值。maximumPossibleForce表示能承受的最大压力值。

无论什么情况,当用户触摸屏幕时,touchesBegan方法会被调用,接着就是touchesMoved(如果用户手指在屏幕上滑动,那么touchedCancelledtouchesEnded也会被调用)。在这个App中,我们只需要关注touchesMoved方法。touchesMoved有两个参数:toucheseventtouches是一个装着UITouch对象的NSSet类型集合(集合无序,并且无重复)。我们必须要确保在touches中只有一个UITouch对象,但也有考虑不完全的时候,所以强烈建议大家先利用可选绑定来判断touches.firsttouches中的第一个UITouch对象)是否是空。在ViewController.swift中添加以下代码:

override func touchesMoved(touches: Set, 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+做了判断。(如果你想学习更多Swift 2.0相关的知识,我就更加推荐你阅读这篇文章了。)同样,如果你的编译环境是iOS9.0+,那么这个判断可以省略。

要得到按压百分比?那太简单了,只需要用force属性除以maximumPossibleForce就可以了(例如:touch.maximumPossibleForce),maximumPossibleForce表示能承受的最大压力值。然后,更新文本:

override func touchesMoved(touches: Set, 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上物体的重量,而不是百分比。根据Ryan McLeod的App可以知道,传感器的计量范围的最大值是385g。因此,maximumPossibleForce就相当于385g(相当于3.8N)。通过简单的计算,就可以把压力百分比转为克。需要做的仅仅是用百分比*385。对于重于385g的物体,就把label改成类似于“385+ grams”这样的文本好了。

到此,touchesMoved方法中的代码更新为:

override func touchesMoved(touches: Set, 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…

还有一个小问题:当物体或者触摸事件结束之后,文本没有重置。你可以实现touchesEnded方法来达到效果:

override func touchesEnded(touches: Set, withEvent event: UIEvent?) {
    forceLabel.text = "0 gram"
}

主屏幕上的快捷操作

另一个3D Touch的用法是主屏幕上的快捷操作。快捷操作可以让用户从快捷方式直接跳转到App的某个地方。按压App icon快捷方式就会出现。在介绍3D Touch的时候,Twitter、Instagram等App就展示了这个新特性。

让我们来给刚才的电子秤App添加一个快捷操作吧(把白色背景换成蓝色)。要添加快捷操作,先打开工程目录中的info.plist(在导航栏上点击工程名,在TARTGET中找到info选项卡)。在这个文件中,添加UIApplicationShortcutItems数组。数组中的元素是包含一个快捷操作配置的字典:

  • UIApplicationShortcutItemType (必填):快捷操作的唯一标识符(String类型)。建议将bundle ID或者其他唯一字符串作为标识符前缀。
  • UIApplicationShortcutItemTitle(必填):相当于快捷操作的title(String类型),用户可以看到。例如“显示最近一张照片”之类的文本。
  • UIApplicationShortcutItemSubtitle(可选):快捷操作的副标题(String类型)。例如“昨天拍摄的照片”。如果你想要给快捷操作添加一个icon,可以自定义,也可以使用系统自带的。
  • UIApplicationShortcutItemIconType(可选):表示你要选择哪种系统图标作为快捷操作的icon(String类型)。
  • UIApplicationShortcutItemIconFile(可选):表示给快捷操作添加自定义icon(String类型)。
  • UIApplicationShortcutItemUserInfo(可选):在快捷操作交互时传递的额外信息(译者注:类似于通知的UserInfo参数)(Dictionary 类型)。

在这个数组中,我们将会给自定义的快捷操作添加4个配置。然后,你的info.plist文件看起来应该是这样滴:

注意,我用到了$(PRODUCT_BUNDLE_IDENTIFIER)来代替com.appcoda.Scale(就是替代的 bundle ID)。这是出于安全考虑:无论在什么情况下,如果我在General中修改了 bundle ID,那整个工程的 bundle ID 就都变了,这势必会给项目带来不晓得影响。这样的话,我就需要手动去修改每个 bundle ID。在info.plist里面可以看到,其实每个 Bundle Identifier 配置项都是用的$(PRODUCT_BUNDLE_IDENTIFIER)来表示 bundle ID 在工程中的路径。

最后一件事,就是实现用户触发快捷操作的处理流程。快捷方式需要在AppDelegate.swiftperformActionForShortcutItem方法中处理。当使用快捷操作启动时,这个方法会被调用。所以,实现这个方法,并在方法中处理快捷操作:

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {

    // Handle quick actions
    completionHandler(handleQuickAction(shortcutItem))

}

这个方法需要调用completionHandler,并传入布尔值,这个布尔值取决于快捷操作成功与否。这里我们封装了一个handleQuickAction方法来处理快捷方式。如果有多个快捷操作,最好的方式是使用枚举,UIApplicationShortcutItemType作为枚举的rawValue(译者注:对枚举不熟悉可以参考这篇文章)。定义一个枚举,并实现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
}

一切都是这么简单。现在把程序跑起来,使用快捷操作来启动App,就可以看到背景已经是蓝色了。

还有一件事

还有一个问题你别忘了…在程序启动顺序方面,启动程序和使用快捷操作唤醒是有区别的。我们都知道,程序启动会调用willFinishLaunchingWithOptionsdidFinishLaunchingWithOptions方法。但是当使用快捷操作唤醒时,只会触发performActionForShortcutItem方法(译者注:这就意味着,使用快捷操作来启动会走三个方法,而使用快捷操作唤醒只会走一个,具体的方法列表如下图)。

如果你回头看didFinishLaunchingWithOptions方法,会发现里面我写了一行设置背景色为白色的代码。这个是在直接启动程序时用的。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions:
    [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    self.window?.backgroundColor = UIColor.whiteColor()

    return true
}

问题来了:当使用快捷操作唤醒程序时,willFinishdidFinishperformActionForShortcutItem都会被调用。所以背景色会先设置成白色,接着又被设置成了蓝色。显然你不想在使用快捷操作启动时,背景色被设置成白色。

要解决这个问题,我们需要在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得到用户是否是通过快捷操作启动。UIApplicationShortcutItem可以作为可选值的类型。如果程序是通过快捷操作启动的,我们可以直接调用handleQuickAction方法将背景色改为蓝色。

因为我们已经在didFinishLaunchingWithOption方法中调用了handleQuickAction,所以没必要再在performActionForShortcutItem方法中调用一次。所以最后我们返回了一个false,告诉系统不要再去调用performActionForShortcutItem方法。

再次运行程序!完美!

最后

3D Touch是给程序添加另一种交互方式的好方法。但是你还是不要忘了,目前还不是所有设备都支持3D Touch。

通过这篇文章,你应该能给你的App添加快捷操作,也能计量按压力度了。

顺便,你可以在这里下载程序的最终版。同样,欢迎大家留言。

【译】3D Touch之我见

Hey,现在有了支持3D Touch的iPhone和iOS9,这是一项伟大的科技杰作。让我们看看这为开发者和用户都带来了什么。文本主要是我对3D Touch的理解,然后列举了一些需要注意的点。

出师不利

本来我想写一篇关于3D Touch的导读文章,但是遇到一个问题——Xcode7的模拟器并不能模拟3D Touch。

苹果官方的说法是:

Xcode7.0中,你必须使用支持3D Touch的真机进行开发。因为Xcode7.0的模拟器不支持3D Touch。

这是个悲伤的故事,但是又有什么办法呢。我想,苹果应该会想办法模拟出来。可能在下一个Xcode发布版本中就能看到。

另一个问题则是新的iPhone还没有在波兰发售,可能还要等2周(译者注:作者写文在波兰iPhone发售以前)。

还有一个办法,我10月要在San Francisco和Palo Alto呆上整整一月,所以我可能会买一部iPhone,但不确定是6s还是6s plus。

如果买了设备,那肯定会发布一大波3D Touch的文章。

Peek and pop操作

这是苹果介绍3D Touch的第一个特性——或者说是两个特性。

  • 轻压(peek,轻度按压)操作能让用户在不离开当前界面的情况下预览内容。如果轻按某个选项能够弹出一个小的矩形视图,则表明它支持轻压操作。
  • peek手势弹出的视图应该足够大,这样内容就不会被手指挡住,从而用户可以选择是否重压,即pop操作(译者注:peek操作即轻按,用于预览,pop操作则是重压,用于进一步确认。pop能满足在预览之后,进入特定页面的需求)。
  • pop则是当用户在peek弹出的视图上加重按压力度,显示更详细的内容。
  • 即使peek能给用户足够多的信息,你也应该让用户将该操作转化为pop。pop所显示的界面应该和用户点击进入界面相同。
  • 请勿在peek预览的界面中放入按钮,因为用户手指一离开预览界面,预览界面就会消失,所以根本点不到按钮。
  • 当用户在预览界面中向上滑动时,peek可以提供一些快捷操作(quick action)。你可以在预览界面中添加一些快捷操作,这样用户就可以上滑,然后选择一个你所提供的操作了。
  • 如果你为某个选项提供了长按手势事件(touch-and-hold,或者叫long press),那么你可以用peek来代替长按手势,这是一个很好的尝试。
  • 如果你想使用快捷操作、peek和pop,那么记住在使用前先判断3D Touch是否可用。
  • 不是每个设备都支持peek和pop操作的,并且3D Touch也可能处于禁用状态。所以不要让某些事件只能由peek来触发。最好有一个备选方案,即视图也能通过长按手势来展示。

快捷操作

接下来,介绍一些用户在重压应用图标时的一些快捷操作。

  • 弹出框包含了主标题、副标题与图标。
  • 该操作可以在应用程序更新时,显示更新信息。
  • 你的应用在Home界面中,应该至少提供一个快捷选项。这样用户就可以使用手势操作你的应用,方便快捷。
  • 医用最多可以提供四个快捷操作。
  • 不要使用快捷操作来提醒用户更新、变更之类的事。如有需要,通知(Notifications)更能胜任这些任务。
  • 快捷操作的命名应该简洁,如有需要,还应该有副标题和图标。尽量让用户明确该操作的作用。如果提供了副标题,那么标题栏将会更长,如果大小不能适应,系统会自动截取。如果没有副标题,那么主标题过长会自动换行。

最后

3D Touch是一个非常爽的特性,它提供了全新的交互方式。设备中包含了一个线性振动器(Taptic Engine),所以按压屏幕时,设备能有一定响应——太好了,迫不及待想要试试。

非常遗憾,苹果没有在最新的Xcode 7 beta 2中解决无法模拟的问题,还是希望他们尽快搞定吧——或许他们不修复是为了增加销量,因为用户已经迫不及待的想要试试这个新特性了,而最简单粗暴的方式,就是买个新设备 :D。

我已经迫不及待的想要尝试基于3D Touch的应用了,如游戏和画图,还有一些我想象不到的应用。或许还可以看到计量重量的应用,比如称一个水果的重量,或是一个放置在屏幕上的物体的重量等等 :>。

时间: 2024-11-05 10:21:46

3D Touch介绍:电子秤App与快捷操作的相关文章

微信成为首批支持iPhone 6s /Plus 上 3D Touch 功能的 App

2015苹果新品发布会上微信成为首批支持iPhone 6s 和 iPhone 6s Plus 上 3D Touch 功能的 App.通过 3D Touch,微信用户将可以通过更精减的操作完成基本任务,包括新建聊天,录制小视频,显示我的二维码或免打扰一小时.用户还可以通过 3D Touch 进行图片缩略图预览:或在聊天页面中启动快速操作菜单,选择标为已读 / 未读,免打扰,置顶或删除. 微信还通过3D Touch推出新功能,让用户可以在发送消息时更改字号或者表情图标的大小.相信微信会给用户带来更多

iOS开发--3D Touch的基本使用

1.桌面快捷菜单项 效果如图: 桌面快捷菜单 点击之后的效果如图: 点击桌面快捷菜单的效果 接下来看下具体实现:1).在-application:didFinishLaunchingWithOptions:方法中用-setShortcutItems:方法来添加快捷菜单项. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //

iOS开发之 3D Touch 开发

在App 的开发中对于开发人员来说新设备以及新功能的适配无疑是一个很苦逼的事.在今年九月份iPhone 6S 以及 6S+ 出来之后,新的功能 3D Touch又是一个比较头疼的事.刚刚看到的时候以为是比较麻烦的东西 看着开发文档就头大(本撸主英语水平有限).但是看完官方文档之后感觉也不是很麻烦.所以就自己写了一个Demo 供大家吐槽和狂喷. 我感觉  3D Touch  的使用和  UITabBar  差不多还是一个比较简单的东西,几乎是拿过来就能用的东西. 一. 给桌面 Icon 添加 3D

iOS9系列专题一——3D Touch

新的触摸体验--iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同的用户交互. 二.在模拟器上学习和测试3D Touch 3D Touch是一个很新颖的设计,可是苹果文档有言: With Xcode 7.0 you must develop on a device that supports 3D Touch. Simu

[转]3D Touch

iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同的用户交互. 二.在模拟器上学习和测试3D Touch 3D Touch是一个很新颖的设计,可是苹果文档有言: With Xcode 7.0 you must develop on a device that supports 3D Touch. Simulator in

3d touch 应用 2 -备用

一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同的用户交互. 二.在模拟器上学习和测试3D Touch 3D Touch 是一个很新颖的设计,可是苹果文档有言: With Xcode 7.0 you must develop on a device that supports 3D Touch. Simulator in Xcode 7.0 do

iOS 3D Touch功能

新的触摸体验--iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同的用户交互. 二.在模拟器上学习和测试3D Touch 3D Touch 是一个很新颖的设计,可是苹果文档有言: With Xcode 7.0 you must develop on a device that supports 3D Touch. Sim

iOS 9之3D Touch

金田 北京时间9月10日凌晨, Apple在美国旧金山比尔格拉汉姆公民大礼堂(Bill Graham Civic Auditorium)召开新品发布会.本次着重介绍了3D Touch功能, 大体介绍一下: - 增强版的Force Touch(压力触控)技术,Force Touch之前被应用在于Apple Watch - 根据力度的不同,从而带来更多样化的用户体验.比如,用力按快进按钮会使快进的速度更快.用力度触摸代替了长按拖拽选项.用力按屏幕时用户可以自行调节应用界面等 - 在点击.滑动.缩放的

iOS9新特性-3D Touch

本文主要讲解3DTouch各种场景下的开发方法,开发主屏幕应用icon上的快捷选项标签(Home Screen Quick Actions),静态设置 UIApplicationShortcutItem ,动态添加.修改UIApplicationShortcutItem,peek和pop的实现. 一.3DTouch开发准备工作(让模拟器也支持 3DTouch 的解决办法) 需要支持3DTouch的设备,如iPhone6s或以上.iOS9或以上.Xcode7或以上,估计很多和我一样的屌丝还没有iP