SlideShare a Scribd company logo
Adopting 3D Touch
Juan Catalan
jcatalan007@gmail.com
Agenda
• What is 3D Touch
• Home Screen Quick actions
• Peek and Pop
• Pressure Sensitivity
What is 3D Touch?
• With the introduction of the iPhone 6s and the iPhone
6s Plus, Apple added 3D Touch, a new dimension to
the multi-touch user interface.
• This new technology senses how deeply users press
the display and provides a new way to interact with
the iPhone.
• In iOS 9, Apple introduced several 3D Touch APIs. In
this session I will explain in a practical way what is 3D
Touch and how you can benefit from it in your app.  
3D Touch at a glance
https://developer.apple.com/ios/3d-touch/
Demo: sample app
Home Screen Quick actions
Home Screen Quick actions
Static
Defined in app’s info.plist
Available when the app is installed
Dynamic
Created by the app at runtime
Available after the first launch of the app
Shown after any static quick actions (if there is enough space)
Can include a system icon, custom icon, or Address Book contact
Home Screen Quick actions
Static
Defined in app’s info.plist
Available when the app is installed
Home Screen Quick actions
Dynamic: creating and registering
func createDynamicShortcuts() {
let application = UIApplication.shared
let bundleIdentifier = Bundle.main.bundleIdentifier!
var items = [UIMutableApplicationShortcutItem]()
if let (favoriteAsset, indexOfFavorite) = AssetStorage.sharedStorage.mostRecentFavoriteAsset() {
let favoriteShortcut = UIMutableApplicationShortcutItem(
type: "(bundleIdentifier).Favorite",
localizedTitle: favoriteAsset.name,
localizedSubtitle: favoriteAsset.detail,
icon: UIApplicationShortcutIcon(type: .love),
userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfFavorite]
)
items.append(favoriteShortcut)
}
let (recentAsset, indexOfRecent) = AssetStorage.sharedStorage.mostRecentNonFavoriteAsset()
let recentShortcut = UIMutableApplicationShortcutItem(
type: "(bundleIdentifier).Recent",
localizedTitle: recentAsset.name,
localizedSubtitle: recentAsset.detail,
icon: UIApplicationShortcutIcon(type: .task),
userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfRecent]
)
items.append(recentShortcut)
application.shortcutItems = items
}
Home Screen Quick actions
Dynamic: creating and registering
func createDynamicShortcuts() {
let application = UIApplication.shared
let bundleIdentifier = Bundle.main.bundleIdentifier!
var items = [UIMutableApplicationShortcutItem]()
if let (favoriteAsset, indexOfFavorite) = AssetStorage.sharedStorage.mostRecentFavoriteAsset() {
let favoriteShortcut = UIMutableApplicationShortcutItem(
type: "(bundleIdentifier).Favorite",
localizedTitle: favoriteAsset.name,
localizedSubtitle: favoriteAsset.detail,
icon: UIApplicationShortcutIcon(type: .love),
userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfFavorite]
)
items.append(favoriteShortcut)
}
let (recentAsset, indexOfRecent) = AssetStorage.sharedStorage.mostRecentNonFavoriteAsset()
let recentShortcut = UIMutableApplicationShortcutItem(
type: "(bundleIdentifier).Recent",
localizedTitle: recentAsset.name,
localizedSubtitle: recentAsset.detail,
icon: UIApplicationShortcutIcon(type: .task),
userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfRecent]
)
items.append(recentShortcut)
application.shortcutItems = items
}
Handling Quick actions
On app activation
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem,
completionHandler: @escaping (Bool) -> Void) {
let handled = handleSortCutItem(shortcutItem)
completionHandler(handled)
}
func handleSortCutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool {
var vcs = (window!.rootViewController as! UINavigationController).viewControllers
if vcs.count > 1 {
vcs.last!.performSegue(withIdentifier: "UnwindToMainSegue", sender: nil)
vcs = (window!.rootViewController as! UINavigationController).viewControllers
}
let main = vcs.first as! MainTableViewController
switch shortcutItem.type {
case "net.bitcrafters.3DTouchDemo.AddAsset":
main.performSegue(withIdentifier: "NewAssetSegue", sender: nil)
case "net.bitcrafters.3DTouchDemo.Favorite":
main.segueForShortcutToDetail(shortcutItem.userInfo?["index"] as! Int)
case "net.bitcrafters.3DTouchDemo.Recent":
main.segueForShortcutToDetail(shortcutItem.userInfo?["index"] as! Int)
default:
return false
}
return true
}
Handling Quick actions
On app launch
var launchedShortcutItem: UIApplicationShortcutItem?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
var performAdditionalHandling = true
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem] as?
UIApplicationShortcutItem {
launchedShortcutItem = shortcutItem
performAdditionalHandling = false
}
createDynamicShortcuts()
return performAdditionalHandling
}
func applicationDidEnterBackground(_ application: UIApplication) {
createDynamicShortcuts()
}
func applicationDidBecomeActive(_ application: UIApplication) {
guard let shortcut = launchedShortcutItem else { return }
let _ = handleSortCutItem(shortcut)
launchedShortcutItem = nil
}
Demo: quick actions
Home Screen Quick actions
Best practices / design considerations
Every app should provide quick actions
Focus on providing quick access to high-value tasks
Make quick actions predictable
Be prepared to handle dynamic quick actions from a previous
version of your app
Don’t add functionality that is only accessible using quick actions
Implement navigation to the desired feature triggered by the shortcut
Update the dynamic shortcuts to have them ready
Peek and Pop
Peek Pop
Preview Commit
Peek and Pop
Registered View Controller Previewed View Controller
Source
Peek and Pop
Conforming to UIViewControllerPreviewDelegate
override func viewDidLoad() {
super.viewDidLoad()
registerForPreviewing(with: self, sourceView: tableView)
}
…
extension MainTableViewController: UIViewControllerPreviewingDelegate {
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) ->
UIViewController? {
guard
let indexPath = tableView.indexPathForRow(at: location),
let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
"DetailViewController") as? DetailViewController
else {
return nil
}
detailViewController.index = indexPath.row
let cellRect = tableView.rectForRow(at: indexPath)
let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView)
previewingContext.sourceRect = sourceRect
return detailViewController
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
show(viewControllerToCommit, sender: self)
}
}
Peek and Pop
Registering for previewing
override func viewDidLoad() {
super.viewDidLoad()
registerForPreviewing(with: self, sourceView: tableView)
}
…
extension MainTableViewController: UIViewControllerPreviewingDelegate {
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) ->
UIViewController? {
guard
let indexPath = tableView.indexPathForRow(at: location),
let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
"DetailViewController") as? DetailViewController
else {
return nil
}
detailViewController.index = indexPath.row
let cellRect = tableView.rectForRow(at: indexPath)
let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView)
previewingContext.sourceRect = sourceRect
return detailViewController
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
show(viewControllerToCommit, sender: self)
}
}
Peek and Pop
Providing a preview view controller
override func viewDidLoad() {
super.viewDidLoad()
registerForPreviewing(with: self, sourceView: tableView)
}
…
extension MainTableViewController: UIViewControllerPreviewingDelegate {
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) ->
UIViewController? {
guard
let indexPath = tableView.indexPathForRow(at: location),
let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
"DetailViewController") as? DetailViewController
else {
return nil
}
detailViewController.index = indexPath.row
let cellRect = tableView.rectForRow(at: indexPath)
let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView)
previewingContext.sourceRect = sourceRect
return detailViewController
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
show(viewControllerToCommit, sender: self)
}
}
Peek and Pop
Committing a preview view controller
override func viewDidLoad() {
super.viewDidLoad()
registerForPreviewing(with: self, sourceView: tableView)
}
…
extension MainTableViewController: UIViewControllerPreviewingDelegate {
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) ->
UIViewController? {
guard
let indexPath = tableView.indexPathForRow(at: location),
let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
"DetailViewController") as? DetailViewController
else {
return nil
}
detailViewController.index = indexPath.row
let cellRect = tableView.rectForRow(at: indexPath)
let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView)
previewingContext.sourceRect = sourceRect
return detailViewController
}
func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
show(viewControllerToCommit, sender: self)
}
}
Demo: peek and pop
Peek and Pop
Using the Storyboard
Demo: storyboard peek & pop
Peek and Pop (Preview quick actions)
Source
Peek and Pop
Adding preview quick actions
// MARK: Preview actions, in DetailViewController
override var previewActionItems : [UIPreviewActionItem] {
var favoriteTitle: String
if asset.favorite {
favoriteTitle = "💔 (self.asset.name)"
} else {
favoriteTitle = "❤ (self.asset.name)"
}
let favoriteAction = UIPreviewAction(title: favoriteTitle, style: .default) { (action,
viewController) in
self.asset.favorite = !self.asset.favorite
AssetStorage.sharedStorage.update(self.asset, atIndex: self.index!)
NotificationCenter.default.post(name: DetailViewController.updateUINotification, object:
nil)
}
let deleteAction = UIPreviewAction(title: "Delete (self.asset.name)", style: .destructive)
{ (action, viewController) in
AssetStorage.sharedStorage.delete(assetAtIndex: self.index!)
NotificationCenter.default.post(name: DetailViewController.updateUINotification, object: nil)
}
return [favoriteAction, deleteAction]
}
Demo: peek and pop
Peek and Pop
Best practices
Content that can be tapped should support Peek and Pop
Return a preview view controller consistently
Don’t take too long in the previewing delegate
Set the previewing context sourceRect
Low-Level Force API
Normalized access to force data
Properties on UITouch: force and maximumPossibleForce
Available on devices that support 3D Touch or Apple Pencil
Low-Level Force API
Using UITouch
override func touchesMoved(_ touches: Set<UITouch>, with 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"
}
}
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
forceLabel.text = "0 gram"
}
http://www.appcoda.com/3d-touch-tutorial/
Demo: Low-Level Force API
3D Touch summary
https://developer.apple.com/ios/3d-touch/
Reference
https://developer.apple.com/ios/3d-touch/
https://developer.apple.com/library/content/
documentation/UserExperience/Conceptual/
Adopting3DTouchOniPhone/index.html
http://www.appcoda.com/3d-touch-tutorial/
Thanks!
• Source code
https://github.com/jcatalan007/3DTouch-talk
• Slides
https://www.slideshare.net/jcatalan007/
adopting-3d-touch-in-your-apps

More Related Content

What's hot

Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
Michael Galpin
 
Material Design and Backwards Compatibility
Material Design and Backwards CompatibilityMaterial Design and Backwards Compatibility
Material Design and Backwards Compatibility
Angelo Rüggeberg
 
Advancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesAdvancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and Gestures
Samsung Developers
 
50 jquery
50 jquery50 jquery
50 jquery
Char Lie
 
Implementing cast in android
Implementing cast in androidImplementing cast in android
Implementing cast in android
Angelo Rüggeberg
 
Design for succcess with react and storybook.js
Design for succcess with react and storybook.jsDesign for succcess with react and storybook.js
Design for succcess with react and storybook.js
Chris Saylor
 
Violet Peña - Storybook: A React Tool For Your Whole Team
Violet Peña - Storybook: A React Tool For Your Whole TeamViolet Peña - Storybook: A React Tool For Your Whole Team
Violet Peña - Storybook: A React Tool For Your Whole Team
Anton Caceres
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
Scott Gardner
 
Eddystone beacons demo
Eddystone beacons demoEddystone beacons demo
Eddystone beacons demo
Angelo Rüggeberg
 
Android Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation DrawerAndroid Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation Drawer
Agus Haryanto
 
Android basic 4 Navigation Drawer
Android basic 4 Navigation DrawerAndroid basic 4 Navigation Drawer
Android basic 4 Navigation Drawer
Eakapong Kattiya
 
Android
AndroidAndroid
Android
Pranav Ashok
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
Peter Friese
 
@Ionic native/google-maps
@Ionic native/google-maps@Ionic native/google-maps
@Ionic native/google-maps
Masashi Katsumata
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple Developers
Peter Friese
 
Android Accessibility
Android AccessibilityAndroid Accessibility
Android Accessibility
Ascii Huang
 
Android basic 3 Dialogs
Android basic 3 DialogsAndroid basic 3 Dialogs
Android basic 3 Dialogs
Eakapong Kattiya
 
Android basic 2 UI Design
Android basic 2 UI DesignAndroid basic 2 UI Design
Android basic 2 UI Design
Eakapong Kattiya
 
MVVM with SwiftUI and Combine
MVVM with SwiftUI and CombineMVVM with SwiftUI and Combine
MVVM with SwiftUI and Combine
Tai Lun Tseng
 

What's hot (20)

Design Patterns for Tablets and Smartphones
Design Patterns for Tablets and SmartphonesDesign Patterns for Tablets and Smartphones
Design Patterns for Tablets and Smartphones
 
Material Design and Backwards Compatibility
Material Design and Backwards CompatibilityMaterial Design and Backwards Compatibility
Material Design and Backwards Compatibility
 
Advancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and GesturesAdvancing the UI — Part 1: Look, Motion, and Gestures
Advancing the UI — Part 1: Look, Motion, and Gestures
 
50 jquery
50 jquery50 jquery
50 jquery
 
Implementing cast in android
Implementing cast in androidImplementing cast in android
Implementing cast in android
 
Design for succcess with react and storybook.js
Design for succcess with react and storybook.jsDesign for succcess with react and storybook.js
Design for succcess with react and storybook.js
 
Violet Peña - Storybook: A React Tool For Your Whole Team
Violet Peña - Storybook: A React Tool For Your Whole TeamViolet Peña - Storybook: A React Tool For Your Whole Team
Violet Peña - Storybook: A React Tool For Your Whole Team
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
 
SwiftUI and Combine All the Things
SwiftUI and Combine All the ThingsSwiftUI and Combine All the Things
SwiftUI and Combine All the Things
 
Eddystone beacons demo
Eddystone beacons demoEddystone beacons demo
Eddystone beacons demo
 
Android Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation DrawerAndroid Sliding Menu dengan Navigation Drawer
Android Sliding Menu dengan Navigation Drawer
 
Android basic 4 Navigation Drawer
Android basic 4 Navigation DrawerAndroid basic 4 Navigation Drawer
Android basic 4 Navigation Drawer
 
Android
AndroidAndroid
Android
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 
@Ionic native/google-maps
@Ionic native/google-maps@Ionic native/google-maps
@Ionic native/google-maps
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple Developers
 
Android Accessibility
Android AccessibilityAndroid Accessibility
Android Accessibility
 
Android basic 3 Dialogs
Android basic 3 DialogsAndroid basic 3 Dialogs
Android basic 3 Dialogs
 
Android basic 2 UI Design
Android basic 2 UI DesignAndroid basic 2 UI Design
Android basic 2 UI Design
 
MVVM with SwiftUI and Combine
MVVM with SwiftUI and CombineMVVM with SwiftUI and Combine
MVVM with SwiftUI and Combine
 

Similar to Adopting 3D Touch in your apps

3D Touch by Karol Kozub, Macoscope
3D Touch by Karol Kozub, Macoscope3D Touch by Karol Kozub, Macoscope
3D Touch by Karol Kozub, Macoscope
Macoscope
 
mobl
moblmobl
mobl
zefhemel
 
Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月
Eihiro Saishu
 
3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS
Rodrigo Borges
 
Day 5
Day 5Day 5
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
mharkus
 
How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)
Giuseppe Filograno
 
What's new in iOS9
What's new in iOS9What's new in iOS9
What's new in iOS9
CocoaHeads France
 
Cocoaheads Montpellier Meetup : 3D Touch for iOS
Cocoaheads Montpellier Meetup : 3D Touch for iOSCocoaheads Montpellier Meetup : 3D Touch for iOS
Cocoaheads Montpellier Meetup : 3D Touch for iOS
Idean France
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
Anton Narusberg
 
Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...
Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...
Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...
Windows Developer
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
Jose Manuel Pereira Garcia
 
Android activity, service, and broadcast recievers
Android activity, service, and broadcast recieversAndroid activity, service, and broadcast recievers
Android activity, service, and broadcast recievers
Utkarsh Mankad
 
Quick Intro to Android Development
Quick Intro to Android DevelopmentQuick Intro to Android Development
Quick Intro to Android Development
Jussi Pohjolainen
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
Hassan Abid
 
What's new in android: jetpack compose 2024
What's new in android: jetpack compose 2024What's new in android: jetpack compose 2024
What's new in android: jetpack compose 2024
Toru Wonyoung Choi
 
shiny.pdf
shiny.pdfshiny.pdf
shiny.pdf
Ashwini Kalantri
 
Leture5 exercise onactivities
Leture5 exercise onactivitiesLeture5 exercise onactivities
Leture5 exercise onactivities
maamir farooq
 
Lecture exercise on activities
Lecture exercise on activitiesLecture exercise on activities
Lecture exercise on activities
maamir farooq
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
Filippo Matteo Riggio
 

Similar to Adopting 3D Touch in your apps (20)

3D Touch by Karol Kozub, Macoscope
3D Touch by Karol Kozub, Macoscope3D Touch by Karol Kozub, Macoscope
3D Touch by Karol Kozub, Macoscope
 
mobl
moblmobl
mobl
 
Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月
 
3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS3D Touch: Preparando sua app para o futuro do iOS
3D Touch: Preparando sua app para o futuro do iOS
 
Day 5
Day 5Day 5
Day 5
 
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
GDG GeorgeTown Devfest 2014 Presentation: Android Wear: A Developer's Perspec...
 
How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)
 
What's new in iOS9
What's new in iOS9What's new in iOS9
What's new in iOS9
 
Cocoaheads Montpellier Meetup : 3D Touch for iOS
Cocoaheads Montpellier Meetup : 3D Touch for iOSCocoaheads Montpellier Meetup : 3D Touch for iOS
Cocoaheads Montpellier Meetup : 3D Touch for iOS
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...
Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...
Build 2017 - B8108 - App engagement in Windows Timeline and Cortana with User...
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Android activity, service, and broadcast recievers
Android activity, service, and broadcast recieversAndroid activity, service, and broadcast recievers
Android activity, service, and broadcast recievers
 
Quick Intro to Android Development
Quick Intro to Android DevelopmentQuick Intro to Android Development
Quick Intro to Android Development
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
What's new in android: jetpack compose 2024
What's new in android: jetpack compose 2024What's new in android: jetpack compose 2024
What's new in android: jetpack compose 2024
 
shiny.pdf
shiny.pdfshiny.pdf
shiny.pdf
 
Leture5 exercise onactivities
Leture5 exercise onactivitiesLeture5 exercise onactivities
Leture5 exercise onactivities
 
Lecture exercise on activities
Lecture exercise on activitiesLecture exercise on activities
Lecture exercise on activities
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
 

Recently uploaded

Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
ThousandEyes
 
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
dream girl
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
87tomato
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
45unexpected
 
Odoo E-commerce website development guides
Odoo E-commerce website development guidesOdoo E-commerce website development guides
Odoo E-commerce website development guides
jhkdigitalmarketing
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
shanihomely
 
Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech
 
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
ashiklo9823
 
Introduction to Cloud computing for Internet of Things
Introduction to Cloud computing for Internet of ThingsIntroduction to Cloud computing for Internet of Things
Introduction to Cloud computing for Internet of Things
NachuSubramanian1
 
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdfIoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
mohitd6
 
Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)
miso_uam
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
kalichargn70th171
 
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
jealousviolet
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
bhumivarma35300
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
neshakor5152
 
welcome to presentation on Google Apps
welcome to   presentation on Google Appswelcome to   presentation on Google Apps
welcome to presentation on Google Apps
AsifKarimJim
 
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
3610stuck
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
Daniel Zivkovic
 
To Avoid Mistakes When Using Online Attendance Sheets
To Avoid Mistakes When Using Online Attendance SheetsTo Avoid Mistakes When Using Online Attendance Sheets
To Avoid Mistakes When Using Online Attendance Sheets
Task Tracker
 
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to KnowThe Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
onemonitarsoftware
 

Recently uploaded (20)

Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
Cisco Live Announcements: New ThousandEyes Release Highlights - July 2024
 
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
 
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
Verified Girls Call Mumbai 👀 9820252231 👀 Cash Payment With Room DeliveryDeli...
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
 
Odoo E-commerce website development guides
Odoo E-commerce website development guidesOdoo E-commerce website development guides
Odoo E-commerce website development guides
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
 
Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.
 
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
 
Introduction to Cloud computing for Internet of Things
Introduction to Cloud computing for Internet of ThingsIntroduction to Cloud computing for Internet of Things
Introduction to Cloud computing for Internet of Things
 
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdfIoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
IoT In Manufacturing_ Use Cases, Benefits, and Challenges.pdf
 
Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
 
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
VVIP Girls Call Mumbai 9910780858 Provide Best And Top Girl Service And No1 i...
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
 
welcome to presentation on Google Apps
welcome to   presentation on Google Appswelcome to   presentation on Google Apps
welcome to presentation on Google Apps
 
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
 
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdfAI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
AI - Your Startup Sidekick (Leveraging AI to Bootstrap a Lean Startup).pdf
 
To Avoid Mistakes When Using Online Attendance Sheets
To Avoid Mistakes When Using Online Attendance SheetsTo Avoid Mistakes When Using Online Attendance Sheets
To Avoid Mistakes When Using Online Attendance Sheets
 
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to KnowThe Ultimate Guide to Phone Spy Apps: Everything You Need to Know
The Ultimate Guide to Phone Spy Apps: Everything You Need to Know
 

Adopting 3D Touch in your apps

  • 1. Adopting 3D Touch Juan Catalan jcatalan007@gmail.com
  • 2. Agenda • What is 3D Touch • Home Screen Quick actions • Peek and Pop • Pressure Sensitivity
  • 3. What is 3D Touch? • With the introduction of the iPhone 6s and the iPhone 6s Plus, Apple added 3D Touch, a new dimension to the multi-touch user interface. • This new technology senses how deeply users press the display and provides a new way to interact with the iPhone. • In iOS 9, Apple introduced several 3D Touch APIs. In this session I will explain in a practical way what is 3D Touch and how you can benefit from it in your app.  
  • 4. 3D Touch at a glance https://developer.apple.com/ios/3d-touch/
  • 7. Home Screen Quick actions Static Defined in app’s info.plist Available when the app is installed Dynamic Created by the app at runtime Available after the first launch of the app Shown after any static quick actions (if there is enough space) Can include a system icon, custom icon, or Address Book contact
  • 8. Home Screen Quick actions Static Defined in app’s info.plist Available when the app is installed
  • 9. Home Screen Quick actions Dynamic: creating and registering func createDynamicShortcuts() { let application = UIApplication.shared let bundleIdentifier = Bundle.main.bundleIdentifier! var items = [UIMutableApplicationShortcutItem]() if let (favoriteAsset, indexOfFavorite) = AssetStorage.sharedStorage.mostRecentFavoriteAsset() { let favoriteShortcut = UIMutableApplicationShortcutItem( type: "(bundleIdentifier).Favorite", localizedTitle: favoriteAsset.name, localizedSubtitle: favoriteAsset.detail, icon: UIApplicationShortcutIcon(type: .love), userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfFavorite] ) items.append(favoriteShortcut) } let (recentAsset, indexOfRecent) = AssetStorage.sharedStorage.mostRecentNonFavoriteAsset() let recentShortcut = UIMutableApplicationShortcutItem( type: "(bundleIdentifier).Recent", localizedTitle: recentAsset.name, localizedSubtitle: recentAsset.detail, icon: UIApplicationShortcutIcon(type: .task), userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfRecent] ) items.append(recentShortcut) application.shortcutItems = items }
  • 10. Home Screen Quick actions Dynamic: creating and registering func createDynamicShortcuts() { let application = UIApplication.shared let bundleIdentifier = Bundle.main.bundleIdentifier! var items = [UIMutableApplicationShortcutItem]() if let (favoriteAsset, indexOfFavorite) = AssetStorage.sharedStorage.mostRecentFavoriteAsset() { let favoriteShortcut = UIMutableApplicationShortcutItem( type: "(bundleIdentifier).Favorite", localizedTitle: favoriteAsset.name, localizedSubtitle: favoriteAsset.detail, icon: UIApplicationShortcutIcon(type: .love), userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfFavorite] ) items.append(favoriteShortcut) } let (recentAsset, indexOfRecent) = AssetStorage.sharedStorage.mostRecentNonFavoriteAsset() let recentShortcut = UIMutableApplicationShortcutItem( type: "(bundleIdentifier).Recent", localizedTitle: recentAsset.name, localizedSubtitle: recentAsset.detail, icon: UIApplicationShortcutIcon(type: .task), userInfo: ["version": Bundle.main.fullVersionNumber!, "index":indexOfRecent] ) items.append(recentShortcut) application.shortcutItems = items }
  • 11. Handling Quick actions On app activation func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { let handled = handleSortCutItem(shortcutItem) completionHandler(handled) } func handleSortCutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool { var vcs = (window!.rootViewController as! UINavigationController).viewControllers if vcs.count > 1 { vcs.last!.performSegue(withIdentifier: "UnwindToMainSegue", sender: nil) vcs = (window!.rootViewController as! UINavigationController).viewControllers } let main = vcs.first as! MainTableViewController switch shortcutItem.type { case "net.bitcrafters.3DTouchDemo.AddAsset": main.performSegue(withIdentifier: "NewAssetSegue", sender: nil) case "net.bitcrafters.3DTouchDemo.Favorite": main.segueForShortcutToDetail(shortcutItem.userInfo?["index"] as! Int) case "net.bitcrafters.3DTouchDemo.Recent": main.segueForShortcutToDetail(shortcutItem.userInfo?["index"] as! Int) default: return false } return true }
  • 12. Handling Quick actions On app launch var launchedShortcutItem: UIApplicationShortcutItem? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. var performAdditionalHandling = true if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem { launchedShortcutItem = shortcutItem performAdditionalHandling = false } createDynamicShortcuts() return performAdditionalHandling } func applicationDidEnterBackground(_ application: UIApplication) { createDynamicShortcuts() } func applicationDidBecomeActive(_ application: UIApplication) { guard let shortcut = launchedShortcutItem else { return } let _ = handleSortCutItem(shortcut) launchedShortcutItem = nil }
  • 14. Home Screen Quick actions Best practices / design considerations Every app should provide quick actions Focus on providing quick access to high-value tasks Make quick actions predictable Be prepared to handle dynamic quick actions from a previous version of your app Don’t add functionality that is only accessible using quick actions Implement navigation to the desired feature triggered by the shortcut Update the dynamic shortcuts to have them ready
  • 15. Peek and Pop Peek Pop Preview Commit
  • 16. Peek and Pop Registered View Controller Previewed View Controller Source
  • 17. Peek and Pop Conforming to UIViewControllerPreviewDelegate override func viewDidLoad() { super.viewDidLoad() registerForPreviewing(with: self, sourceView: tableView) } … extension MainTableViewController: UIViewControllerPreviewingDelegate { func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { guard let indexPath = tableView.indexPathForRow(at: location), let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return nil } detailViewController.index = indexPath.row let cellRect = tableView.rectForRow(at: indexPath) let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView) previewingContext.sourceRect = sourceRect return detailViewController } func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { show(viewControllerToCommit, sender: self) } }
  • 18. Peek and Pop Registering for previewing override func viewDidLoad() { super.viewDidLoad() registerForPreviewing(with: self, sourceView: tableView) } … extension MainTableViewController: UIViewControllerPreviewingDelegate { func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { guard let indexPath = tableView.indexPathForRow(at: location), let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return nil } detailViewController.index = indexPath.row let cellRect = tableView.rectForRow(at: indexPath) let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView) previewingContext.sourceRect = sourceRect return detailViewController } func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { show(viewControllerToCommit, sender: self) } }
  • 19. Peek and Pop Providing a preview view controller override func viewDidLoad() { super.viewDidLoad() registerForPreviewing(with: self, sourceView: tableView) } … extension MainTableViewController: UIViewControllerPreviewingDelegate { func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { guard let indexPath = tableView.indexPathForRow(at: location), let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return nil } detailViewController.index = indexPath.row let cellRect = tableView.rectForRow(at: indexPath) let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView) previewingContext.sourceRect = sourceRect return detailViewController } func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { show(viewControllerToCommit, sender: self) } }
  • 20. Peek and Pop Committing a preview view controller override func viewDidLoad() { super.viewDidLoad() registerForPreviewing(with: self, sourceView: tableView) } … extension MainTableViewController: UIViewControllerPreviewingDelegate { func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { guard let indexPath = tableView.indexPathForRow(at: location), let detailViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return nil } detailViewController.index = indexPath.row let cellRect = tableView.rectForRow(at: indexPath) let sourceRect = previewingContext.sourceView.convert(cellRect, from: tableView) previewingContext.sourceRect = sourceRect return detailViewController } func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { show(viewControllerToCommit, sender: self) } }
  • 22. Peek and Pop Using the Storyboard
  • 24. Peek and Pop (Preview quick actions) Source
  • 25. Peek and Pop Adding preview quick actions // MARK: Preview actions, in DetailViewController override var previewActionItems : [UIPreviewActionItem] { var favoriteTitle: String if asset.favorite { favoriteTitle = "💔 (self.asset.name)" } else { favoriteTitle = "❤ (self.asset.name)" } let favoriteAction = UIPreviewAction(title: favoriteTitle, style: .default) { (action, viewController) in self.asset.favorite = !self.asset.favorite AssetStorage.sharedStorage.update(self.asset, atIndex: self.index!) NotificationCenter.default.post(name: DetailViewController.updateUINotification, object: nil) } let deleteAction = UIPreviewAction(title: "Delete (self.asset.name)", style: .destructive) { (action, viewController) in AssetStorage.sharedStorage.delete(assetAtIndex: self.index!) NotificationCenter.default.post(name: DetailViewController.updateUINotification, object: nil) } return [favoriteAction, deleteAction] }
  • 27. Peek and Pop Best practices Content that can be tapped should support Peek and Pop Return a preview view controller consistently Don’t take too long in the previewing delegate Set the previewing context sourceRect
  • 28. Low-Level Force API Normalized access to force data Properties on UITouch: force and maximumPossibleForce Available on devices that support 3D Touch or Apple Pencil
  • 29. Low-Level Force API Using UITouch override func touchesMoved(_ touches: Set<UITouch>, with 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" } } } } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { forceLabel.text = "0 gram" } http://www.appcoda.com/3d-touch-tutorial/
  • 33. Thanks! • Source code https://github.com/jcatalan007/3DTouch-talk • Slides https://www.slideshare.net/jcatalan007/ adopting-3d-touch-in-your-apps