際際滷

際際滷Share a Scribd company logo
Implementing 3D Touch
in iOS 9 - BTTF Style
Andrew Kozlik
Requirements
 iOS 9
 Xcode 7
 iPhone 6S or 6S Plus
 ALWAYS check to make sure force touch is available
func isForceTouchAvailable() -> Bool {
var isForceTouchAvailable = false;
if (self.traitCollection.respondsToSelector("forceTouchCapability")) {
isForceTouchAvailable = self.traitCollection.forceTouchCapability == UIForceTouchCapability.Available
}
return isForceTouchAvailable
}
Shortcut Example
Static Shortcuts
 Shortcuts are added to Info.plist
 Array - UIApplicationShortcutItems
 Each item contains keys including:
 UIApplicationShortcutItemIconFile
 UIApplicationShortcutItemTitle
 UIApplicationShortcutItemType
 UIApplicationShortcutItemUserInfo
Info.plist example
Dynamic Shortcuts
 Create an array of UIMutableApplicationShortcutItems
 Arguments Include:
 type
 localizedTitle
 localizedSubtitle
 icon
 userInfo
 Set UIApplication singleton shorcutItems property
Code Sample
func loadShortcutItems() {
var shortcutItems = [UIMutableApplicationShortcutItem]()
// Loop through each character and create shortcuts
for character in characters! {
let item = UIMutableApplicationShortcutItem(
type: "com.codefortravel.backtothefuture.character",
localizedTitle: character.characterName!,
localizedSubtitle: "Tap for more details",
icon: nil, // No icon
// icon: UIApplicationShortcutIcon(templateImageName: "flux-
capacitor")
// icon: UIApplicationShortcutIcon(type: .Add),
userInfo: ["characterName" : character.characterName!]
)
shortcutItems.append(item)
}
UIApplication.sharedApplication().shortcutItems = shortcutItems
}
Responding to Shortcuts
 Application delegate implements
application:performActionForShortcutItem:
 Shortcut type identi鍖es different shortcuts
 Properties can be passed through userInfo
 Usage examples:
 Perform UI updates
 Handle deeplinking
performActionForShortcutItem
func application(application: UIApplication, performActionForShortcutItem shortcutItem:
UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
if (shortcutItem.type == "com.codefortravel.backtothefuture.fluxcapacitor") {
let VC = getRootController() as! ViewController
VC.switchTimeTravelButtonLabel()
} else if (shortcutItem.type == "com.codefortravel.backtothefuture.character") {
let characterName = shortcutItem.userInfo!["characterName"] as? String
let VC = getRootController() as! ViewController
VC.loadDetailForCharacter(characterName!)
}
}
func getRootController() -> UIViewController? {
let navVC = self.window?.rootViewController as? UINavigationController
let VCs = navVC?.viewControllers as [UIViewController]?
if (VCs?.count > 0) {
let VC = VCs![0] as! ViewController
return VC
}
return nil
}
Update UI Code Sample
func switchTimeTravelButtonLabel() {
var message = message1985;
if (buttonTimeTravel?.titleLabel?.text == message1985) {
message = message2015
}
buttonTimeTravel?.setTitle(message, forState: UIControlState.Normal)
}
Deeplink Code Sample
func loadDetailForCharacter(characterName : String) {
let filteredCharacters = characters.filter() {
$0.characterName == characterName
}
if (filteredCharacters.count > 0) {
let character = filteredCharacters[0]
let detailVC = storyboard?.instantiateViewControllerWithIdentifier(
"CharacterDetailViewController") as? CharacterDetailViewController
detailVC?.character = character
self.navigationController?.popToRootViewControllerAnimated(false)
self.showViewController(detailVC!, sender: self)
}
}
Shortcut Limitations
 Maximum of four menu items
 Your app must support deep linking for view controllers
for maximum value
 Shortcuts support up to two lines of text and one icon
 Icons must be square, single color, and 35x35 points
 User may turn 3D touch off, so monitor for changes to
traitCollections
 Always test to ensure 3D touch is available
Testing in Simulator
 SBShortcutMenuSimulator
 https://github.com/DeskConnect/
SBShortcutMenuSimulator
 Adds 3D touch ability to simulator
Peek and Pop Functionality
Implementation Steps
 Check that 3D touch is available
 Register the presenting VC as a preview delegate
 Implement
previewingContext:viewControllerForLocation
 Implement previewingContext:commitViewController
previewingContext:viewControllerForLocation
 Register view with registerForPreviewingWithDelegate
 Pass in view to detect force touch
 Method returns CGPoint indicating where in the view 3D
touch was implemented
 For UITableViews and UICollectionViews, get the cell
located at that point
 Handle any business logic
 Instantiate the preview view controller and return
Code Sample
func previewingContext(previewingContext: UIViewControllerPreviewing,
viewControllerForLocation location: CGPoint) -> UIViewController? {
let indexPath = tableView?.indexPathForRowAtPoint(location)
let row = indexPath?.row
let character = characters[row!]
let detailVC =
storyboard?.instantiateViewControllerWithIdentifier("CharacterDetailViewCo
ntroller") as? CharacterDetailViewController
detailVC?.character = character
detailVC?.preferredContentSize = CGSize(width: 0, height: 280)
return detailVC
}
previewingContext:viewControllerToCommit
 Executed when user does second 3D touch action
 Handle any 鍖nal logic
 Call showViewController to display the VC in full
screen
func previewingContext(previewingContext: UIViewControllerPreviewing,
commitViewController viewControllerToCommit: UIViewController) {
showViewController(viewControllerToCommit, sender: self)
}
Parting Words of Advice
 Never use 3D touch as a primary interaction mechanism
 Use it to add optional functionality
 Educate your users that it exists
 Measure user engagement to determine best shortcuts
 Consider long press to replace 3D touch when
unavailable
Resources
 Apple - Getting Started with 3D Touch
 Laurenz.io - Peek and Pop Tutorial
 the-nerd.be - Another Peek and Pop Tutorial
Outta Time
 Andrew Kozlik
 @codefortravel
 UniKey
 https://github.com/akozlik/Back-to-the-Future
 Code for Orlando
Credits
 Icon made by DKNG - http://modular4kc.com/
2014/07/11/17065/

More Related Content

What's hot (10)

Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With Robolectric
Danny Preussler
Android in practice
Android in practiceAndroid in practice
Android in practice
Jose Manuel Ortega Candel
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
Bruno Salvatore Belluccia
Automated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platformsAutomated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platforms
jobandesther
Unity3D Plugins Development Guide
Unity3D Plugins Development GuideUnity3D Plugins Development Guide
Unity3D Plugins Development Guide
KaiJung Chen
Plugin For Unity
Plugin For UnityPlugin For Unity
Plugin For Unity
Dat Pham
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Giorgio Cefaro
Avoid loss of hair while coding Unity3D plugins for mobile
Avoid loss of hair while coding Unity3D plugins for mobileAvoid loss of hair while coding Unity3D plugins for mobile
Avoid loss of hair while coding Unity3D plugins for mobile
Codemotion
jQuery Ecosystem
jQuery EcosystemjQuery Ecosystem
jQuery Ecosystem
Andrea Balducci
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
guest9bcef2f
Android Unit Testing With Robolectric
Android Unit Testing With RobolectricAndroid Unit Testing With Robolectric
Android Unit Testing With Robolectric
Danny Preussler
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
Bruno Salvatore Belluccia
Automated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platformsAutomated testing of mobile applications on multiple platforms
Automated testing of mobile applications on multiple platforms
jobandesther
Unity3D Plugins Development Guide
Unity3D Plugins Development GuideUnity3D Plugins Development Guide
Unity3D Plugins Development Guide
KaiJung Chen
Plugin For Unity
Plugin For UnityPlugin For Unity
Plugin For Unity
Dat Pham
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Nanos gigantium humeris insidentes (design patterns inside symfony 2)
Giorgio Cefaro
Avoid loss of hair while coding Unity3D plugins for mobile
Avoid loss of hair while coding Unity3D plugins for mobileAvoid loss of hair while coding Unity3D plugins for mobile
Avoid loss of hair while coding Unity3D plugins for mobile
Codemotion
Non Conventional Android Programming En
Non Conventional Android Programming EnNon Conventional Android Programming En
Non Conventional Android Programming En
guest9bcef2f

Similar to 3D Touch Implementation for Shortcuts and Peek/Pop Functionality (20)

Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
Nataliya Patsovska
iOS: A Broad Overview
iOS: A Broad OverviewiOS: A Broad Overview
iOS: A Broad Overview
Chris Farrell
Programming iOS in C#
Programming iOS in C#Programming iOS in C#
Programming iOS in C#
Frank Krueger
Adopting 3D Touch in your apps
Adopting 3D Touch in your appsAdopting 3D Touch in your apps
Adopting 3D Touch in your apps
Juan C Catalan
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-insEclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Tonny Madsen
04 objective-c session 4
04  objective-c session 404  objective-c session 4
04 objective-c session 4
Amr Elghadban (AmrAngry)
Tools and practices for rapid application development
Tools and practices for rapid application developmentTools and practices for rapid application development
Tools and practices for rapid application development
Zolt叩n V叩radi
Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++
ppd1961
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
KatyShimizu
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
KatyShimizu
Cucumber meets iPhone
Cucumber meets iPhoneCucumber meets iPhone
Cucumber meets iPhone
Erin Dees
Modern app development with Jetpack Compose.pptx
Modern app development with Jetpack Compose.pptxModern app development with Jetpack Compose.pptx
Modern app development with Jetpack Compose.pptx
Md Shamsul Arafin Mahtab
Objective c runtime
Objective c runtimeObjective c runtime
Objective c runtime
Inferis
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to Swift
Elmar Kretzer
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
anistar sung
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application Architecture
Mark Trostler
Session 210 _accessibility_for_ios
Session 210 _accessibility_for_iosSession 210 _accessibility_for_ios
Session 210 _accessibility_for_ios
cheinyeanlim
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
iOS app dev Training - Session1
iOS app dev Training - Session1iOS app dev Training - Session1
iOS app dev Training - Session1
Hussain Behestee
XCUITest for iOS App Testing and how to test with Xcode
XCUITest for iOS App Testing and how to test with XcodeXCUITest for iOS App Testing and how to test with Xcode
XCUITest for iOS App Testing and how to test with Xcode
pCloudy
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
Nataliya Patsovska
iOS: A Broad Overview
iOS: A Broad OverviewiOS: A Broad Overview
iOS: A Broad Overview
Chris Farrell
Programming iOS in C#
Programming iOS in C#Programming iOS in C#
Programming iOS in C#
Frank Krueger
Adopting 3D Touch in your apps
Adopting 3D Touch in your appsAdopting 3D Touch in your apps
Adopting 3D Touch in your apps
Juan C Catalan
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-insEclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Tonny Madsen
Tools and practices for rapid application development
Tools and practices for rapid application developmentTools and practices for rapid application development
Tools and practices for rapid application development
Zolt叩n V叩radi
Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++Generalized Functors - Realizing Command Design Pattern in C++
Generalized Functors - Realizing Command Design Pattern in C++
ppd1961
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
KatyShimizu
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
KatyShimizu
Cucumber meets iPhone
Cucumber meets iPhoneCucumber meets iPhone
Cucumber meets iPhone
Erin Dees
Modern app development with Jetpack Compose.pptx
Modern app development with Jetpack Compose.pptxModern app development with Jetpack Compose.pptx
Modern app development with Jetpack Compose.pptx
Md Shamsul Arafin Mahtab
Objective c runtime
Objective c runtimeObjective c runtime
Objective c runtime
Inferis
Migrating Objective-C to Swift
Migrating Objective-C to SwiftMigrating Objective-C to Swift
Migrating Objective-C to Swift
Elmar Kretzer
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
anistar sung
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application Architecture
Mark Trostler
Session 210 _accessibility_for_ios
Session 210 _accessibility_for_iosSession 210 _accessibility_for_ios
Session 210 _accessibility_for_ios
cheinyeanlim
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
iOS app dev Training - Session1
iOS app dev Training - Session1iOS app dev Training - Session1
iOS app dev Training - Session1
Hussain Behestee
XCUITest for iOS App Testing and how to test with Xcode
XCUITest for iOS App Testing and how to test with XcodeXCUITest for iOS App Testing and how to test with Xcode
XCUITest for iOS App Testing and how to test with Xcode
pCloudy

More from Andrew Kozlik (7)

Slack Development and You
Slack Development and YouSlack Development and You
Slack Development and You
Andrew Kozlik
Leveraging parse.com for Speedy Development
Leveraging parse.com for Speedy DevelopmentLeveraging parse.com for Speedy Development
Leveraging parse.com for Speedy Development
Andrew Kozlik
How to start developing iOS apps
How to start developing iOS appsHow to start developing iOS apps
How to start developing iOS apps
Andrew Kozlik
Core data orlando i os dev group
Core data   orlando i os dev groupCore data   orlando i os dev group
Core data orlando i os dev group
Andrew Kozlik
Mwyf presentation
Mwyf presentationMwyf presentation
Mwyf presentation
Andrew Kozlik
Last Ace of Space Postmortem
Last Ace of Space PostmortemLast Ace of Space Postmortem
Last Ace of Space Postmortem
Andrew Kozlik
Generating revenue with AdMob
Generating revenue with AdMobGenerating revenue with AdMob
Generating revenue with AdMob
Andrew Kozlik
Slack Development and You
Slack Development and YouSlack Development and You
Slack Development and You
Andrew Kozlik
Leveraging parse.com for Speedy Development
Leveraging parse.com for Speedy DevelopmentLeveraging parse.com for Speedy Development
Leveraging parse.com for Speedy Development
Andrew Kozlik
How to start developing iOS apps
How to start developing iOS appsHow to start developing iOS apps
How to start developing iOS apps
Andrew Kozlik
Core data orlando i os dev group
Core data   orlando i os dev groupCore data   orlando i os dev group
Core data orlando i os dev group
Andrew Kozlik
Mwyf presentation
Mwyf presentationMwyf presentation
Mwyf presentation
Andrew Kozlik
Last Ace of Space Postmortem
Last Ace of Space PostmortemLast Ace of Space Postmortem
Last Ace of Space Postmortem
Andrew Kozlik
Generating revenue with AdMob
Generating revenue with AdMobGenerating revenue with AdMob
Generating revenue with AdMob
Andrew Kozlik

3D Touch Implementation for Shortcuts and Peek/Pop Functionality

  • 1. Implementing 3D Touch in iOS 9 - BTTF Style Andrew Kozlik
  • 2. Requirements iOS 9 Xcode 7 iPhone 6S or 6S Plus ALWAYS check to make sure force touch is available func isForceTouchAvailable() -> Bool { var isForceTouchAvailable = false; if (self.traitCollection.respondsToSelector("forceTouchCapability")) { isForceTouchAvailable = self.traitCollection.forceTouchCapability == UIForceTouchCapability.Available } return isForceTouchAvailable }
  • 4. Static Shortcuts Shortcuts are added to Info.plist Array - UIApplicationShortcutItems Each item contains keys including: UIApplicationShortcutItemIconFile UIApplicationShortcutItemTitle UIApplicationShortcutItemType UIApplicationShortcutItemUserInfo
  • 6. Dynamic Shortcuts Create an array of UIMutableApplicationShortcutItems Arguments Include: type localizedTitle localizedSubtitle icon userInfo Set UIApplication singleton shorcutItems property
  • 7. Code Sample func loadShortcutItems() { var shortcutItems = [UIMutableApplicationShortcutItem]() // Loop through each character and create shortcuts for character in characters! { let item = UIMutableApplicationShortcutItem( type: "com.codefortravel.backtothefuture.character", localizedTitle: character.characterName!, localizedSubtitle: "Tap for more details", icon: nil, // No icon // icon: UIApplicationShortcutIcon(templateImageName: "flux- capacitor") // icon: UIApplicationShortcutIcon(type: .Add), userInfo: ["characterName" : character.characterName!] ) shortcutItems.append(item) } UIApplication.sharedApplication().shortcutItems = shortcutItems }
  • 8. Responding to Shortcuts Application delegate implements application:performActionForShortcutItem: Shortcut type identi鍖es different shortcuts Properties can be passed through userInfo Usage examples: Perform UI updates Handle deeplinking
  • 9. performActionForShortcutItem func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) { if (shortcutItem.type == "com.codefortravel.backtothefuture.fluxcapacitor") { let VC = getRootController() as! ViewController VC.switchTimeTravelButtonLabel() } else if (shortcutItem.type == "com.codefortravel.backtothefuture.character") { let characterName = shortcutItem.userInfo!["characterName"] as? String let VC = getRootController() as! ViewController VC.loadDetailForCharacter(characterName!) } } func getRootController() -> UIViewController? { let navVC = self.window?.rootViewController as? UINavigationController let VCs = navVC?.viewControllers as [UIViewController]? if (VCs?.count > 0) { let VC = VCs![0] as! ViewController return VC } return nil }
  • 10. Update UI Code Sample func switchTimeTravelButtonLabel() { var message = message1985; if (buttonTimeTravel?.titleLabel?.text == message1985) { message = message2015 } buttonTimeTravel?.setTitle(message, forState: UIControlState.Normal) }
  • 11. Deeplink Code Sample func loadDetailForCharacter(characterName : String) { let filteredCharacters = characters.filter() { $0.characterName == characterName } if (filteredCharacters.count > 0) { let character = filteredCharacters[0] let detailVC = storyboard?.instantiateViewControllerWithIdentifier( "CharacterDetailViewController") as? CharacterDetailViewController detailVC?.character = character self.navigationController?.popToRootViewControllerAnimated(false) self.showViewController(detailVC!, sender: self) } }
  • 12. Shortcut Limitations Maximum of four menu items Your app must support deep linking for view controllers for maximum value Shortcuts support up to two lines of text and one icon Icons must be square, single color, and 35x35 points User may turn 3D touch off, so monitor for changes to traitCollections Always test to ensure 3D touch is available
  • 13. Testing in Simulator SBShortcutMenuSimulator https://github.com/DeskConnect/ SBShortcutMenuSimulator Adds 3D touch ability to simulator
  • 14. Peek and Pop Functionality
  • 15. Implementation Steps Check that 3D touch is available Register the presenting VC as a preview delegate Implement previewingContext:viewControllerForLocation Implement previewingContext:commitViewController
  • 16. previewingContext:viewControllerForLocation Register view with registerForPreviewingWithDelegate Pass in view to detect force touch Method returns CGPoint indicating where in the view 3D touch was implemented For UITableViews and UICollectionViews, get the cell located at that point Handle any business logic Instantiate the preview view controller and return
  • 17. Code Sample func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { let indexPath = tableView?.indexPathForRowAtPoint(location) let row = indexPath?.row let character = characters[row!] let detailVC = storyboard?.instantiateViewControllerWithIdentifier("CharacterDetailViewCo ntroller") as? CharacterDetailViewController detailVC?.character = character detailVC?.preferredContentSize = CGSize(width: 0, height: 280) return detailVC }
  • 18. previewingContext:viewControllerToCommit Executed when user does second 3D touch action Handle any 鍖nal logic Call showViewController to display the VC in full screen func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) { showViewController(viewControllerToCommit, sender: self) }
  • 19. Parting Words of Advice Never use 3D touch as a primary interaction mechanism Use it to add optional functionality Educate your users that it exists Measure user engagement to determine best shortcuts Consider long press to replace 3D touch when unavailable
  • 20. Resources Apple - Getting Started with 3D Touch Laurenz.io - Peek and Pop Tutorial the-nerd.be - Another Peek and Pop Tutorial
  • 21. Outta Time Andrew Kozlik @codefortravel UniKey https://github.com/akozlik/Back-to-the-Future Code for Orlando
  • 22. Credits Icon made by DKNG - http://modular4kc.com/ 2014/07/11/17065/