Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
An introduction to 3D Touch for Swift developers
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
simon gladman
October 19, 2015
Programming
580
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
An introduction to 3D Touch for Swift developers
My Swift London talk of October 19, 2015 discussing 3D Touch for Swift
simon gladman
October 19, 2015
More Decks by simon gladman
See All by simon gladman
Image Processing for iOS
flexmonkey
0
1.5k
Introducing Image Processing in Metal
flexmonkey
0
510
iOS GPU Programming with Swift & Metal
flexmonkey
2
530
Creating Apps Without Interface Builder
flexmonkey
0
500
iOS GPU Programming with Swift & Metal
flexmonkey
4
36k
Other Decks in Programming
See All in Programming
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
Kotlinの15年とServer-Side Kotlin
n_takehata
1
150
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
R8 の設定見直しでアプリサイズ削減
andpad
0
220
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
140
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
sbt 2.0: takeoff
eed3si9n
0
160
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.2k
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
1k
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
610
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
35
17k
Featured
See All Featured
So, you think you're a good person
axbom
PRO
2
2.2k
Design in an AI World
tapps
1
350
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
The agentic SEO stack - context over prompts
schlessera
0
970
Faster Mobile Websites
deanohume
310
32k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
Skip the Path - Find Your Career Trail
mkilby
1
260
Docker and Python
trallard
47
4.2k
Bash Introduction
62gerente
615
220k
Building the Perfect Custom Keyboard
takai
2
910
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Transcript
3D TOUCH An introduction to 3D Touch for Swift developers
Simon Gladman for Swift London / October 2015
HELLO FLEX MONKEY • Blog: flexmonkey.blogspot.co.uk • GitHub: github.com/FlexMonkey •
Twitter: @FlexMonkey
3D TOUCH FOR USERS
3D TOUCH FOR USERS • Peek
3D TOUCH FOR USERS • Peek • Preview Actions
3D TOUCH FOR USERS • Peek • Preview Actions •
Pop
3D TOUCH FOR USERS • Peek • Preview Actions •
Pop • Quick Actions
3D TOUCH FOR USERS • Peek • Preview Actions •
Pop • Quick Actions • Pressure Sensitivity
3D TOUCH FOR DEVS • Simple API • Check device
supports 3D Touch traitCollection.forceTouchCapability == UIForceTouchCapability.Available
• Simple API • Getting force value override func touchesBegan(touches:
Set<UITouch>, withEvent event: UIEvent?) { guard let touch = touches.first else { return } let normalisedForce = touch.force / touch.maximumPossibleForce print(normalisedForce) }
• Simple API • Implementing peek and pop registerForPreviewingWithDelegate(delegate, sourceView:
sourceView) • sourceView reacts to deep press • delegate must implement UIViewControllerPreviewingDelegate
• Peeking & Popping with Previewing Delegate • Protocol contains
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
• Peeking & Popping with Previewing Delegate • Protocol contains
func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController)
3D TOUCH: PEEKING • Peeking - a deep press func
previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
• Peeking func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?
{ let peek = PeekViewController(hsl: hsl, delegate: previewingContext.delegate) return peek }
• Peeking let hsl: HSL unowned let delegate: UIViewControllerPreviewingDelegate required
init(hsl: HSL, delegate: UIViewControllerPreviewingDelegate) { self.hsl = hsl self.delegate = delegate super.init(nibName: nil, bundle: nil) let color = UIColor(hue: hsl.hue, saturation: hsl.saturation, brightness: hsl.lightness, alpha: 1) label.text = "Your color: \(color.getHex())" label.textAlignment = NSTextAlignment.Center smallSwatch.backgroundColor = color }
None
3D TOUCH: PREVIEW ACTIONS • Preview Actions • The previewing
delegate simply needs to implement previewActions()
• Preview Actions enum ColorPresets: String { case Red, Green,
Blue } var previewActions: [UIPreviewActionItem] { return [ColorPresets.Red, ColorPresets.Green, ColorPresets.Blue].map { UIPreviewAction(title: $0.rawValue, style: UIPreviewActionStyle.Default, handler: { (previewAction, viewController) in (viewController as? PeekViewController)?.updateColor(previewAction) }) } }
• Preview Actions func updateColor(previewAction: UIPreviewActionItem) { guard let delegate
= delegate as? ChromaTouchViewController, preset = ColorPresets(rawValue: previewAction.title) else { return } let hue: CGFloat switch preset { case .Blue: hue = 0.667 case .Green: hue = 0.333 case .Red: hue = 0 } delegate.hsl = HSL(hue: hue, saturation: 1, lightness: 1) }
None
3D TOUCH: POPPING • Popping - a deeper press func
previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController)
• Popping func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) { swatch.userInteractionEnabled
= false hslSlidersStackView.hidden = true }
None
3D TOUCH: PRESSURE SENSITIVITY • Touch gestures have ‘x’ and
‘y’ coordinates • Now have a ‘z’ coordinate corresponding to the pressure of the touch
• Override touchesMoved(): override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
{ guard let touch = touches.first else { return } let touchLocation = touch.locationInView(self) let force = touch.force let maximumPossibleForce = touch.maximumPossibleForce let normalisedXPosition = touchLocation.x / frame.width let normalisedYPosition = touchLocation.y / frame.height let normalisedZPosition = force / maximumPossibleForce hsl = HSL(hue: normalisedXPosition, saturation: normalisedYPosition, lightness: normalisedZPosition) sendActionsForControlEvents(.ValueChanged) }
None
GESTURE RECOGNISERS • As an alternative to overriding a control’s
touch handling methods • By extending UIGestureRecognizer let deepPressGestureRecognizer = DeepPressGestureRecognizer(target: self, action: "deepPressHandler:", threshold: 0.75) button.addGestureRecognizer(deepPressGestureRecognizer)
• Handle user’s actions in gesture recogniser’s touch handlers override
func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) { guard let view = view, touch = touches.first where touch.force != 0 && touch.maximumPossibleForce != 0 else { return } if !deepPressed && (touch.force / touch.maximumPossibleForce) >= threshold { state = UIGestureRecognizerState.Began deepPressed = true } else if deepPressed && (touch.force / touch.maximumPossibleForce) < threshold { state = UIGestureRecognizerState.Ended deepPressed = false } }
TOUCH COALESCING • touchesMoved() samples at up to 60 hertz
TOUCH COALESCING • touchesMoved() samples at up to 60 hertz
• iPhone 6s has a touch sample rate of 120 hertz
TOUCH COALESCING • touchesMoved() samples at up to 60 hertz
• iPhone 6s has a touch sample rate of 120 hertz • iPad Pro will sample touches at 240 hertz
• The missing touches can be accessed through the event’s
coalescedTouches override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { super.touchesMoved(touches, withEvent: event) guard let touch = touches.first, coalescedTouches = event?.coalescedTouchesForTouch(touch) else { return } for coalescedTouch in coalescedTouches { let locationInView = coalescedTouch.locationInView(view) print(locationInView) } }
None
SOME DEMO APPS
None
None
None
None
None
http://goo.gl/rzPExI flexmonkey.blogspot.co.uk github.com/FlexMonkey