Если вы задаетесь вопросом, почему Force Touch было переименовано на 3D Touch для iPhone, тогда вы не одни такой. Вскоре после того, как Крейг Федериги (Craig Federighi), который также был явно озадачен названием, представил эту новую возможность, возникло много догадок. Чем не устроило название Force Touch? Слишком много шуток из Звездных войн?
Но есть разница! Очевидно, что Force Touch может распознать только сильное нажатие, тогда как функция 3D Touch более чувствительная и может выделить несколько уровней нажатий на основе того, как сильно вы нажимаете.
Хотя изменения могут показаться незначительными, именно они позволяют разработчикам сделать измерения на iPhone более точными. Возьмите это приложение Gravity, например, которое превращает ваш iPhone в цифровые весы с помощью Force Touch. Хотя оно и было отклонено компанией Apple по неясным причинам, идея замечательная. Таким образом, чтобы показать вам, как работает 3D Touch, давайте попробуем сделать похожее приложение!
Давайте начнем
Для начала скачайте этот шаблон проекта, который я создал. По сути, это просто пустое приложение создание на основе шаблона Single View iPhone application. Я создал проект разместил (UILabels & UIImage) и подключил IBOutlets в ViewController.swift.
Дизайн нашего приложения довольно прост: у нас есть один контроллер с 2 метками: одна это заголовок и вторая метка, которая показывает процент силы нажатия на экран iPhone.
Давайте начнем разработку! На iPhone 6s и 6s Plus у объектов UITouch есть два новых свойства типа CGFloat, под названием force и maximumPossibleForce. Force представляет, то насколько сильным является касание, где 1.0 означает среднее касание. MaximumPossibleForce показывает максимальную силу для касания.
Всякий раз, когда пользователь нажимает на сенсор, вызывается метод touchesBegan, а затем touchesMoved, если пользователь водит своим пальцем по экрану, то тогда вызывается touchedCancelled или TouchesEnded в зависимости от ситуации. Для наших целей метод touchesMoved является единственным способом, который нам нужен. TouchesMoved имеет два параметра: touches (касания) и event (событие). Касания — набор (неупорядоченный набор различных объектов) объектов UITouch. Для касания должен быть точно один объект UITouch, но мы можем быть не достаточно осторожными, поэтому настоятельно рекомендуется проверить, равен ли touches.first (первый объект UITouch сенсорного набора) 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 Store, это является обязательным требованием, выполнение проверки, так как более старые устройства такие как iPhone 6 не поддерживают 3D Touch.
Обратите внимание на то, что я также проверял, запускается ли устройство на iOS 9.0 или более поздних версиях. Я делаю это с помощью нового синтаксиса #available, представленного в Swift 2.0. Если Вы хотите узнать больше о новых функциях и возможностях в Swift 2.0, я рекомендую вам прочитать эту статью. Снова эта проверка необязательна, если ваша целевая платформа для приложения 9.0 или выше.
Чтобы получить силу нажатия в процентах, просто разделите силу касания на максимальную силу (т.е. touch.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"
}
}
}
}
Если запустите приложение на iPhone 6s/6s Plus, оно должно показать силу нажатия в процентах при нажатии на экран. Однако так как мы делаем шкалу, возможно вы захотите добавить количество граммов, которые вы взвешиваете на своем iPhone. Согласно Райану Маклиду, датчик взвесит максимальный веса ~385g. Таким образом maximumPossibleForce соответствует 385 граммам (приблизительно 3.8 Ньютона). Путем нехитрых вычислений, вы можете конвертировать % силы в граммы. Все, что нам нужно сделать, это умножить процент силы нажатия на 385. Для объектов весом 385 граммов или больше, мы просто изменяем метку на “385+ grams”.
Теперь обновите метод, используя следующий фрагмент кода:
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"
}
}
}
}
}
Круто! Вы сделали свое Digital Scale приложения.
На данный момент приложение не сбрасывает вес до нуля после того, как вы убираете предмет или прекращаете касаться вашего экрана. Вы можете реализовать touchesEnded метод, чтобы сбросить метку.
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
forceLabel.text = "0 gram"
}
Быстрые действия на главном экране
Еще одно отличное использование 3D Touch — это быстрые действия на главном экране. Quick Actions дают пользователям меню для перехода к каталогу вашего приложения напрямую. Просто сильно нажмите на значок программы, и вы увидите меню. С появлением технологий 3D Touch, такие приложения как Twitter и Instagram и некоторые других приложения, показали как используют эту новую функцию.
Давайте добавим Quick Actions для нашего приложение которое мы только что сделали, с помощью которого мы будет открывает приложение с синим фоном вместо белого. Чтобы добавить Quick Actions, откройте файл info.plist Вашего проекта (Щелкните по рабочей области Scale в навигаторе проекта, выберите Scale target и перейдите на вкладку Info). В файле добавьте ‘UIApplicationShortcutItems’ тип выберите массив (Array). Каждый элемент массива представляет собой словарь, содержащий свойства одного быстрого действия:
- UIApplicationShortcutItemType (обязательно): строка, которая идентифицирует быстрое действие. Обратите внимание, что эта строка должна быть уникальной, определенно для приложения. Хорошая идея состоит в том, чтобы добавить префикс с помощью Вашего идентификатора или некоторых других хитростями для того что бы сделать уникальную строку.
- UIApplicationShortcutItemTitle (обязательно): строка, представляет заголовок для Quick Action который показывается пользователю. Примером может быть “Show last picture taken”.
- UIApplicationShortcutItemSubtitle (необязательно): строка для названия вашего Quick Action. Примером может быть“Last picture taken yesterday”. Если вы хотите добавить иконку для Quick Action, у вас есть два варианта: системная иконка от Apple или пользовательская иконка.
- UIApplicationShortcutItemIconType (необязательно): строка, указывающая, какая системная иконка будет отображаться рядом с Quick Action.
- UIApplicationShortcutItemIconFile (необязательно): строка, указывающая, какая пользовательская иконка будет отображаться рядом с Quick Action.
- UIApplicationShortcutItemUserInfo (необязательно): словарь, содержащий некоторую дополнительную информацию, которую вы хотите выполнить с помощью Quick Action.
В массиве мы определяем четыре элементов для настройки Quick Action «OpenBlue». Теперь info.plist должен выглядеть следующим образом:
Обратите внимание, что я использовал ‘$(PRODUCT_BUNDLE_IDENTIFIER)’ вместо ‘com.appcoda.Scale’ или любой другой идентификатор, который вы используете. Это в целях безопасности: если, по какой-либо причине, я изменю Bundle ID в ‘General’, то будет затронут весь проект и идентификатор будет изменен везде. В противном случае, мне придется менять его везде вручную. В вашем файле info.plist, вы можете увидеть, что ключ Bundle Identifier использует тот же подход: '$(PRODUCT_BUNDLE_IDENTIFIER)' описывает путь к идентификатору вашего проекта.
Последнее, что осталось сделать, это реализовать Quick action, когда пользователь запускает его. Главная работа обрабатываются в AppDelegate.swift в методе performActionForShortcutItem. Когда Quick Action активируется, вызовется метод. Поэтому вы должны реализовывать этот метод для обработки быстрых действий:
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
// Handle quick actions
completionHandler(handleQuickAction(shortcutItem))
}
Как ожидается, вызовите обработчик и передадите в него нулевое значение, в зависимости от успеха/отказа быстрого действия. Здесь мы создаем отдельную функцию handleQuickAction, чтобы обработать действие. Отличным способом для представления нескольких случаев Quick Action является использование перечислений с помощью ‘UIApplicationShortcutItemType’ в качестве необработанного значения. Объявите перечисление и реализуйте метод 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 Action. Так как Вы знаете, когда приложение запускается, вызываются методы willFinishLaunchingWithOptions затем метод anddidFinishLaunchingWithOptions. Но когда приложение возобновляется путем Quick Actions, то он лишь провоцирует выполнение метода 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
}
Вот откуда исходит проблема: при запуске приложения с помощью быстрое действие, вызываются willFinish, didFinish, а затем performActionForShortcutItem. Поэтому сначала устанавливается белый цвет фона, а затем меняется на синий. Очевидно, Вы не хотите устанавливать цвет фона белым, когда пользователь запускает приложение с помощью быстрых действий.
Чтобы решить эту проблему, мы должны осуществить проверку в методе 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
}
Чтобы определить, запущено ли приложение посредством Quick Action, Вы можете проверить функциональную клавишу запуска UIApplicationLaunchOptionsShortcutItemKey. Объект UIApplicationShortcutItem доступен как значение функциональной клавиши запуска. Если приложение запущено путем Quick Action, мы просто вызываем handleQuickAction, чтобы изменить фон на синий.
Поскольку мы уже обработали быстрое действие в didFinishLaunchingWithOptions, мы не хотим вызывать performActionForShortcutItem, чтобы выполнить handleQuickAction снова. Потому мы возвращаем значение false, сообщая системе не вызывать метод performActionForShortcutItem.
Вот и все! Вы можете теперь протестировать приложение. Quick Action должно работать отлично.
Итог
3D Touch — отличный способ добавления удобных и приятных функций к Вашему приложению. Однако Вы должны знать, что не все устройства поддерживают 3D Touch, хотя это может измениться в будущем.
После прочтения этой статьи вы сможете добавлять Quick Actions к вашему iOS приложению и определять силу касания.
Для сравнения вы можете загрузить полный проект Xcode. Не забудьте поделиться мыслями в комментариях об этом руководстве и 3D Touch.
Комментарии (7)
norlin
20.11.2015 12:08Но есть разница! Очевидно, что Force Touch может распознать только сильное нажатие, тогда как функция 3D Touch более чувствительная и может выделить несколько уровней нажатий на основе того, как сильно вы нажимаете.
Force-touch на макбуке выдаёт несколько уровней. Не знаю, сколько именно оно различает, но выглядит, как будто непрерывное измерение силы нажатия.
Это можно легко проверить, если у вас есть новый макбук или тачпад – откройте в Safari любой сайт, наведите курсор на какое-нибудь слово и начинайте потихоньку усиливать давление на тачпад.
Увидите, что ещё до щелчка слово начинает подсвечиваться, а потом начинает выползать попап (причём, подсветка и выползание усиливаются от нажима, и исчезают обратно, если ослабить нажим)
Более того, в настройках тачпада можно выбрать его «жёсткость» – то есть, при какой силе нажатия срабатывает щелчок отдачи.yarmolchuk
20.11.2015 13:05Я могу с вами согласится. Но как по мне то все же это немного разные технологий, но очень похожи между собой. Специально пошел на сайт apple и посмотрел что они пишут.
О Force Touch.
The new Force Touch trackpad takes all the capabilities of Multi-Touch and adds force sensors that detect subtle differences in the amount of downward pressure you apply. This lets you have a deeper connection to your content, bringing more functionality right to your fingertip. It also introduces haptic feedback to MacBook Pro — allowing you not just to see what’s happening on the screen, but to feel it.
О 3D Touch.
iPhone 6s introduces an entirely new way to interact with your phone. For the ?rst time, iPhone senses how much pressure you apply to the display. In addition to familiar Multi?Touch gestures like Tap, Swipe, and Pinch, 3D Touch introduces Peek and Pop. This brings a new dimension of functionality to the iPhone experience. And when you use 3D Touch, your iPhone responds with subtle taps. So not only will you see what a press can do — you’ll feel it.norlin
20.11.2015 13:41На 146% уверен, это маркетинговая чушь. Технология одна и та же, судя по всему.
sojik
Это ваш ответ на просьбу Apple не использовать экран телефона как весы? :)))
https://tjournal.ru/p/apple-3dtouch-scales
yarmolchuk
Если есть такая возможность использовать когда это нужно, то почему бы и не использовать?
valeriyvan
Кому-то покажется, что раз можно взвешивать 100 грамм, можно и килограмм. «Ну я же не знаю какой вес, пока не взвешу. Попробовал взвесить, а телефон сломался.» Представьте поток жалоб идиотов с продавленными экранами, которые будут утверждать что использовали приложения из AppStore, поэтому Apple обязана заменить разбитый экран бесплатно. Поэтому и запретили. Не надо поощрять идиотов использовать аппараты таким способом, который убьет аппараты.