Adopting New Trackpad Features - Apple...

Post on 04-Jun-2018

220 views 0 download

Transcript of Adopting New Trackpad Features - Apple...

© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

Adopting New Trackpad FeaturesMastering the force

Master Raleigh Ledet AppKit Engineer

App Frameworks

Session 217

#WWDC15

Force Touch Trackpad

Force Touch Trackpad

Force Touch Trackpad

Force Touch Trackpad

Force Touch Trackpad

Force sensor

Force sensor

Force sensor

Force sensor

Force Touch Trackpad

Force sensor

Force sensor

Force sensor

Force sensor

Taptic Engine

Force Touch Trackpad

Force sensor

Force sensor

Force sensor

Force sensor

Taptic Engine

Force Touch Trackpad

Force sensor

Force sensor

Force sensor

Force sensor

Taptic Engine

Force Touch Trackpad

Force sensor

Force sensor

Force sensor

Force sensor

Taptic Engine

Force Touch Trackpad

Force sensor

Force sensor

Force sensor

Force sensor

Taptic Engine

Force Touch Trackpad

Force Touch Trackpad

Click

Force Touch Trackpad

Force Touch Trackpad

Force Click

Force Touch Trackpad

Force Touch Trackpad

Demo

Force Touch Trackpad

Force Touch Trackpad

Training ScheduleBecoming a master in one day!

Squire• Accelerator Controls, Table Row Actions

Knight• Force Event Stream, Spring Loading, Alignment Feedback

Master• Configuration and Haptics

SquireUsing the built-in tools

Squire Training ScheduleUsing the built-in tools

Table Row Actions Spring Loaded ControlsAccelerator Controls

Table Row ActionsCase Study: Mail message list

Table Row ActionsCase Study: Mail message list

Table Row ActionsCase Study: Mail message list

NSTableViewDelegate optional func tableView(NSTableView, rowActionsForRow: NSInteger, edge: NSTableRowActionEdge) -> [NSTableViewRowAction]

Table Row ActionsCase Study: Mail message list

NSTableViewDelegate optional func tableView(NSTableView, rowActionsForRow: NSInteger, edge: NSTableRowActionEdge) -> [NSTableViewRowAction]

.Leading

.Trailing

Table Row ActionsCase Study: Mail message list

NSTableViewRowAction convenience init(style: NSTableViewRowActionStyle, title: String, handler: ((NSTableViewRowAction, Int) -> Void))

Table Row ActionsCase Study: Mail message list

NSTableViewRowAction convenience init(style: NSTableViewRowActionStyle, title: String, handler: ((NSTableViewRowAction, Int) -> Void))

Table Row ActionsCase Study: Mail message list

NSTableViewRowAction convenience init(style: NSTableViewRowActionStyle, title: String, handler: ((NSTableViewRowAction, Int) -> Void))

.Regular

.Destructive

Table Row ActionsCase Study: Mail message list

Table Row ActionsCase Study: Mail message list

Spring Loaded ControlsCase Study: Finder Drag and Drop Navigation

Spring Loaded ControlsCase Study: Finder Drag and Drop Navigation

Spring Loaded ControlsCase Study: Finder Drag and Drop Navigation

NSButton

var springLoaded: Bool

Spring Loaded ControlsCase Study: Finder Drag and Drop Navigation

NSButton

var springLoaded: Bool

Spring Loaded ControlsCase Study: Finder Drag and Drop Navigation

NSSegmentedControl

var springLoaded: Bool

Spring Loaded ControlsCase Study: Finder Drag and Drop Navigation

NSSegmentedControl

var springLoaded: Bool

Accelerator ControlsCase Study: Quicktime Player

Accelerator ControlsCase Study: Quicktime Player

Accelerator ControlsCase Study: Quicktime Player

Accelerator ControlsCase Study: Quicktime Player

NSButton

func setButtonType(NSButtonType) .AcceleratorButton .MultiLevelAcceleratorButton

Accelerator ControlsCase Study: Quicktime Player

NSButton

func setButtonType(NSButtonType) .AcceleratorButton .MultiLevelAcceleratorButton

Accelerator ControlsCase Study: Quicktime Player

NSButton

func setButtonType(NSButtonType) .AcceleratorButton .MultiLevelAcceleratorButton

var doubleValue: Double Range: 0,[1-2]

Accelerator ControlsCase Study: Quicktime Player

NSButton

func setButtonType(NSButtonType) .AcceleratorButton .MultiLevelAcceleratorButton

var doubleValue: Double Range: [0-5]

var maxAcceleratorLevel: Int Range: [1-5]

Accelerator ControlsCase Study: Quicktime Player

NSButton

func setButtonType(NSButtonType) .AcceleratorButton .MultiLevelAcceleratorButton

var doubleValue: Double Range: [0-5]

var maxAcceleratorLevel: Int Range: [1-5]

Accelerator ControlsCase Study: Quicktime Player

NSButton

func setButtonType(NSButtonType) .AcceleratorButton .MultiLevelAcceleratorButton

var doubleValue: Double

0 1 2 3 4 5

1X 2X 5X 10X 30X 60x

Accelerator ControlsCase Study: Maps

Accelerator ControlsCase Study: Maps

Accelerator ControlsCase Study: Maps

NSSegmentedControl

var trackingMode: NSSegmentSwitchTracking .MomentaryAccelerator

Accelerator ControlsCase Study: Maps

NSSegmentedControl

var trackingMode: NSSegmentSwitchTracking .MomentaryAccelerator

Accelerator ControlsCase Study: Maps

NSSegmentedControl

var trackingMode: NSSegmentSwitchTracking .MomentaryAccelerator

func doubleValueForSelectedSegment() -> Double Range: 0,[1-2]

Accelerator ControlsCase Study: Photos

Accelerator ControlsCase Study: Photos

Accelerator ControlsCase Study: Photos

NSControl

var continuous: Bool

Accelerator ControlsCase Study: Photos

NSControl

var continuous: Bool

Accelerator ControlsNSButton, NSSegmentedControl

Accelerated

Continuous

Time

Maps: +/- zoom buttons

Photos: previous / next photo button

Accelerator ControlsNSButton, NSSegmentedControl

Accelerated

Continuous

Time

Maps: +/- zoom buttons

Photos: previous / next photo button

Accelerator ControlsNSButton, NSSegmentedControl

Accelerated

Continuous

Time

Maps: +/- zoom buttons

Photos: previous / next photo button

Accelerator ControlsNSButton, NSSegmentedControl

Accelerated

Continuous

Time

Maps: +/- zoom buttons

Photos: previous / next photo button

Squire SummaryUsing the built-in tools

Table Row Actions Spring Loaded ControlsAccelerator Controls

KnightUnderstanding how the force flows

Knight Training ScheduleUnderstanding how the force flows

Force event streamSpring loading protocolAlignment feedback

Event Stream

Event Stream

NSLeftMouseDown

NSLeftMouseDragged

NSLeftMouseUp

NSKeyUp

NSKeyDown

NSRightMouseDown

NSRightMouseDragged

NSRightMouseUp

NSMouseEntered

NSMouseExited NSFlagsChanged

NSScrollWheel

NSEventTypeMagnify

NSEventTypeRotate

Event StreamPressure Gesture

NSLeftMouseDown

NSLeftMouseDragged

NSLeftMouseUp

NSKeyUp

NSKeyDown

NSRightMouseDown

NSRightMouseDragged

NSRightMouseUp

NSMouseEntered

NSMouseExited NSFlagsChanged

NSScrollWheel

NSEventTypeMagnify

NSEventTypeRotate

NSEventTypePressure

Event StreamPressure Gesture

NSLeftMouseDownMask

NSLeftMouseDraggedMask

NSLeftMouseUpMask

NSKeyUpMask

NSKeyDownMask

NSRightMouseDownMask

NSRightMouseDraggedMask

NSRightMouseUpMask

NSMouseEnteredMask

NSMouseExitedMask NSFlagsChangedMask

NSScrollWheelMask

NSEventMaskMagnify

NSEventMaskRotate

NSEventMaskPressure

Event StreamPressure Gesture

NSLeftMouseDraggedMask NSLeftMouseUpMask NSEventMaskPressure, ,

trackEventsMatchingMask(NSEventMask,…)

[ ]

Event StreamPressure Gesture

trackEventsMatchingMask(NSEventMask,…)

[.LeftMouseDraggedMask, .LeftMouseUpMask, .EventMaskPressure]

Event StreamPressure Gesture

trackEventsMatchingMask(NSEventMask,…)

func pressureChangeWithEvent(NSEvent)

[.LeftMouseDraggedMask, .LeftMouseUpMask, .EventMaskPressure]

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } .Began -> .Changed -> .Ended

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

1 - click

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

1 - click

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

1 - click 2 - force click

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

1 - click 2 - force click

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

1 - click 2 - force click 0 - gesture release

Event StreamPressure Gesture

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var stage: Int { get }

1 - click 2 - force click 0 - gesture release

21.0

0.0

Stage 1

Force

Pres

sure

Event StreamPressure Gesture

NSEventTypePressure

var pressure: Float { get } (of the current stage) Range: [0-1]

1.0

0.0

Pres

sure

Event StreamPressure Gesture

NSEventTypePressure

var pressure: Float { get } (of the current stage) Range: [0-1]

2Stage 1

Force

1.0

0.0

Pres

sure

Event StreamPressure Gesture

NSEventTypePressure

var pressure: Float { get } (of the current stage) Range: [0-1]

2Stage 1

Force

Event StreamPressure Gesture

NSEventTypePressure

var pressure: Float { get } var stageTransition: CGFloat { get } Range: [0-1]

1.0

0.0

Stag

e Tra

nsiti

on

2Stage 1

Force

Event StreamPressure Gesture

NSEventTypePressure

var pressure: Float { get } var stageTransition: CGFloat { get } Range: [0-1]

1.0

0.0

Stag

e Tra

nsiti

on

2Stage 1

Force

Event StreamPressure Gesture

NSEventTypePressure

var pressure: Float { get } var stageTransition: CGFloat { get } Range: [0-1]

1.0

0.0

Stag

e Tra

nsiti

on

2Stage 1

Force

User Action

Stage:

Mouse:Events

Forc

e on

trac

kpad

Pres

sure

Event StreamParallel Mouse and Pressure event streams

Time

1

0

Click threshold

Force Click threshold

User Action

Stage:

Mouse:Events

Forc

e on

trac

kpad

Pres

sure

Event StreamParallel Mouse and Pressure event streams

Time

1

0

Click threshold

Force Click threshold

User Action

Stage:

Mouse:Events

Forc

e on

trac

kpad

Pres

sure

Event StreamParallel Mouse and Pressure event streams

Time

1

0

Click threshold

Force Click threshold

User Action

Stage:

Mouse:Events

Forc

e on

trac

kpad

Pres

sure

Event StreamParallel Mouse and Pressure event streams

Time

1

0

Click threshold

Force Click threshold

User Action

Stage:

Mouse:Events

Forc

e on

trac

kpad

Pres

sure

Event StreamParallel Mouse and Pressure event streams

Time

1

0

Click threshold

Force Click threshold

Event StreamParallel Mouse and Pressure event streams

Time

Stage:

Mouse:

-

Move

1

0

Click threshold

Force Click threshold

Forc

e on

trac

kpad

Pres

sure

Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Stage:

Mouse:

-

Move

1

0

Click threshold

Force Click threshold

Forc

e on

trac

kpad

Pres

sure

Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

1

0

Click threshold

Force Click threshold

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

1

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

1

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

21

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

21

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

21

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

21

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

21

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2 11

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2

Up

011

0

Click threshold

Force Click threshold

Dragged

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2

Up

011

0

Click threshold

Force Click threshold

Dragged Move

-

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

Time

Down

1-

Move

2

Up

011

0

Click threshold

Force Click threshold

Dragged Move

-

Forc

e on

trac

kpad

Pres

sure

Stage:

Mouse:Events

User Action

Event StreamParallel Mouse and Pressure event streams

var associatedEventMask: NSEventMask { get }

Event StreamParallel Mouse and Pressure event streams

var associatedEventMask: NSEventMask { get }

if ((mouseDown.associatedEventMask.contains(.EventMaskPressure)) { // Pressure Capable Device! }

Event StreamSummary

NSEventTypePressure NSEventMaskPressure var phase: NSEventPhase { get } var pressure: Float { get } var stage: Int { get } var stageTransition: CGFloat { get } var associatedEventMask: NSEventMask { get }

func pressureChangeWithEvent(NSEvent)

Spring Loading

@protocol NSSpringLoadingDestination

Spring Loading

@protocol NSSpringLoadingDestination required (One of these) func springLoadingEntered(NSDraggingInfo) -> NSSpringLoadingOptions

- and / or - func springLoadingUpdated(NSDraggingInfo) -> NSSpringLoadingOptions

@protocol NSSpringLoadingDestination required (One of these) func springLoadingEntered(NSDraggingInfo) -> NSSpringLoadingOptions

- and / or - func springLoadingUpdated(NSDraggingInfo) -> NSSpringLoadingOptions

Spring Loading

.Disabled

.Enabled

Spring Loading

@protocol NSSpringLoadingDestination required (One of these) func springLoadingEntered(NSDraggingInfo) -> NSSpringLoadingOptions

- and / or - func springLoadingUpdated(NSDraggingInfo) -> NSSpringLoadingOptions

.Disabled

.Enabled

.ContinuousActivation

Spring Loading

@protocol NSSpringLoadingDestination required (One of these) func springLoadingEntered(NSDraggingInfo) -> NSSpringLoadingOptions

- and / or - func springLoadingUpdated(NSDraggingInfo) -> NSSpringLoadingOptions

.Disabled

.Enabled

.ContinuousActivation

.NoHover

Spring Loading

@protocol NSSpringLoadingDestination required (One of these) func springLoadingEntered(NSDraggingInfo) -> NSSpringLoadingOptions

- and / or - func springLoadingUpdated(NSDraggingInfo) -> NSSpringLoadingOptions

@optional func springLoadingExited(NSDraggingInfo) func draggingEnded(NSDraggingInfo)

Spring Loading

@protocol NSSpringLoadingDestination @required func springLoadingActivated(Bool, draggingInfo: NSDraggingInfo) func springLoadingHighlightChanged(NSDraggingInfo)

Spring Loading

@protocol NSSpringLoadingDestination @required func springLoadingActivated(Bool, draggingInfo: NSDraggingInfo) func springLoadingHighlightChanged(NSDraggingInfo)

draggingInfo.springLoadingHighlight

NSSpringLoadingHighlight .None .Standard .Emphasized

Spring Loading

NSSpringLoadingDestination

Alignment Feedback

Alignment Feedback

Alignment Feedback

Tracking Loop

Tracking Loop

MouseUp?

move Item

nextEvent

Alignment Feedback

eventMaskfunc mouseDown()

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

MouseUp?

move Item

nextEvent

NSAlignmentFeedbackFilter

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

class func inputEventMask() -> NSEventMask

MouseUp?

move Item

nextEvent

NSAlignmentFeedbackFilter

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

MouseUp?

NSAlignmentFeedbackFiltermove Item

nextEvent

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

func updateWithEvent(NSEvent)

MouseUp?

NSAlignmentFeedbackFiltermove Item

nextEvent

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

MouseUp?

NSAlignmentFeedbackFiltermove Item

nextEvent

func updateWithPanRecognizer(NSPanGestureRecognizer)

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

MouseUp?

NSAlignmentFeedbackFiltermove Item

nextEvent

setNeedsDisplay()

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

MouseUp?

setNeedsDisplay()

NSAlignmentFeedbackFilter

prepareAlignment

move Item

nextEvent

Tracking Loop

eventMaskfunc mouseDown()

Alignment Feedback

MouseUp?

setNeedsDisplay()

NSAlignmentFeedbackFilter

prepareAlignment

move Item

nextEvent

Alignment FeedbackPreparing alignment

previous

Alignment FeedbackPreparing alignment

previous

default

Alignment FeedbackPreparing alignment

previous

default

Alignment FeedbackPreparing alignment

previous

default

Alignment FeedbackPreparing alignment

previous

default

Alignment Feedback

previous

default

Preparing alignment

aligned

func alignmentFeedbackTokenForHorizontalMovementInView(NSView?, previousX: CGFloat, alignedX: CGFloat, defaultX: CGFloat) -> NSAlignmentFeedbackToken?

Alignment Feedback

previous

default

Preparing alignment

aligned

func alignmentFeedbackTokenForHorizontalMovementInView(NSView?, previousX: CGFloat, alignedX: CGFloat, defaultX: CGFloat) -> NSAlignmentFeedbackToken?

func alignmentFeedbackTokenForVerticalMovementInView(NSView?, previousY: CGFloat, alignedY: CGFloat, defaultY: CGFloat) -> NSAlignmentFeedbackToken?

Alignment Feedback

previous

default

Preparing alignment

aligned

func alignmentFeedbackTokenForHorizontalMovementInView(NSView?, previousX: CGFloat, alignedX: CGFloat, defaultX: CGFloat) -> NSAlignmentFeedbackToken?

func alignmentFeedbackTokenForVerticalMovementInView(NSView?, previousY: CGFloat, alignedY: CGFloat, defaultY: CGFloat) -> NSAlignmentFeedbackToken?

Alignment Feedback

previous

default

Preparing alignment

aligned

func alignmentFeedbackTokenForMovementInView(NSView?, previousPoint: NSPoint, alignedPoint: NSPoint, defaultPoint: NSPoint) -> NSAlignmentFeedbackToken?

Tracking Loop

eventMaskfunc mouseDown()

MouseUp?

setNeedsDisplay()

Alignment Feedback

NSAlignmentFeedbackFilter

prepareAlignment

move Item

nextEvent

Tracking Loop

eventMaskfunc mouseDown()

MouseUp?

setNeedsDisplay()

Alignment Feedback

NSAlignmentFeedbackFilter

[<Token>]

prepareAlignment

move Item

nextEvent

Tracking Loop

eventMaskfunc mouseDown()

MouseUp?

setNeedsDisplay()

Alignment Feedback

NSAlignmentFeedbackFilter

performFeedback

[<Token>]

prepareAlignment

move Item

nextEvent

Tracking Loop

eventMaskfunc mouseDown()

MouseUp?

setNeedsDisplay()

Alignment Feedback

NSAlignmentFeedbackFilter

performFeedback

[<Token>]

prepareAlignment

move Item

func performFeedback([<NSAlignmentFeedbackToken>], performanceTime: NSHapticFeedbackPerformanceTime)

nextEvent

Alignment FeedbackFeeling it

Consistent feel across appsEasy to integrate into tracking loopsDragging, resizing, etc…

Knight SummaryUnderstanding how the force flows

Force event streamSpring loading protocolAlignment Feedback

MasterControlling the force

Master Training ScheduleControlling the force

Trackpad configurationHaptics

Trackpad ConfigurationMore than just Force Click

NSPressureConfiguration

Trackpad ConfigurationMore than just Force Click

NSPressureConfiguration

init(pressureBehavior: NSPressureBehavior)

Trackpad ConfigurationMore than just Force Click

NSPressureConfiguration

init(pressureBehavior: NSPressureBehavior)

.PrimaryDefault

.PrimaryClick

.PrimaryGeneric

.PrimaryAccelerator

.PrimaryDeepClick

.PrimaryDeepDrag

Trackpad ConfigurationMore than just Force Click

NSPressureConfiguration

init(pressureBehavior: NSPressureBehavior) func set()

Trackpad ConfigurationMore than just Force Click

NSPressureConfiguration

init(pressureBehavior: NSPressureBehavior) func set()

Set is not ideal• Only valid during a drag• Racing the user

Trackpad ConfigurationMore than just Force Click

Preferred approach: NSView - var pressureConfiguration: NSPressureConfiguration

• Configured before mouse down• Configured when app not responsive

HapticsThe Trackpad Strikes Back

HapticsThe Trackpad Strikes Back

Use sparinglySubtle interactions

HapticsThe Trackpad Strikes Back

NSHapticFeedbackManager class func defaultPerformer() -> <NSHapticFeedbackPerformer>

@protocol NSHapticFeedbackPerformer <NSObject> func performFeedbackPattern(NSHapticFeedbackPattern, performanceTime: NSHapticFeedbackPerformanceTime)

HapticsThe Trackpad Strikes Back

NSHapticFeedbackManager class func defaultPerformer() -> <NSHapticFeedbackPerformer>

@protocol NSHapticFeedbackPerformer <NSObject> func performFeedbackPattern(NSHapticFeedbackPattern, performanceTime: NSHapticFeedbackPerformanceTime)

HapticsThe Trackpad Strikes Back

NSHapticFeedbackManager class func defaultPerformer() -> <NSHapticFeedbackPerformer>

@protocol NSHapticFeedbackPerformer <NSObject> func performFeedbackPattern(NSHapticFeedbackPattern, performanceTime: NSHapticFeedbackPerformanceTime)

NSHapticFeedbackPattern .Generic .Alignment .LevelChange

NSHapticFeedbackManager class func defaultPerformer() -> <NSHapticFeedbackPerformer>

@protocol NSHapticFeedbackPerformer <NSObject> func performFeedbackPattern(NSHapticFeedbackPattern, performanceTime: NSHapticFeedbackPerformanceTime)

HapticsThe Trackpad Strikes Back

NSHapticFeedbackPerformanceTime .Default .Now .DrawCompleted

Summary

Table Row ActionsAccelerator ButtonsSpring LoadingPressure Event StreamAlignment FeedbackConfiguration Haptic Feedback

More Information

DocumentationForceTouchCatalogAlignmentGuideshttp://developer.apple.com/library

Technical SupportApple Developer Forumshttp://developer.apple.com/forums

General InquiriesPaul MarcosApp Frameworks Evangelistpmarcos@apple.com

Related Sessions

What’s New in Web Development in WebKit and Safari Mission Tuesday 9:00AM

What’s New in Cocoa Presidio Tuesday 1:30PM

What’s New in NSCollection View Mission Thursday 4:30PM

Labs

Cocoa and Force Touch and Gestures Lab Frameworks Lab A Thursday 11:00AM

Cocoa and NSCollectionView Lab Frameworks Lab B Friday 9:00AM