Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
An introduction to 3D Touch for Swift developers
Search
simon gladman
October 19, 2015
Programming
570
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.4k
Introducing Image Processing in Metal
flexmonkey
0
500
iOS GPU Programming with Swift & Metal
flexmonkey
2
510
Creating Apps Without Interface Builder
flexmonkey
0
480
iOS GPU Programming with Swift & Metal
flexmonkey
4
36k
Other Decks in Programming
See All in Programming
Vite+ Unified Toolchain for the Web
naokihaba
0
310
RTSPクライアントを自作してみた話
simotin13
0
610
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
260
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
630
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
690
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
540
dRuby over BLE
makicamel
2
340
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.2k
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
340
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
250
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.7k
Featured
See All Featured
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
160
GitHub's CSS Performance
jonrohan
1033
470k
[SF Ruby Conf 2025] Rails X
palkan
2
1.1k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
55k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
590
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
200
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
140
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Git: the NoSQL Database
bkeepers
PRO
432
67k
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