41
3DTOUCH COCOAHEADS - MONTPELLIER - 14 AVRIL 2016 [email protected] https://github.com/leverdeterre

Cocoaheads Montpellier Meetup : 3D Touch for iOS

Embed Size (px)

Citation preview

3DTOUCHCOCOAHEADS - MONTPELLIER - 14 AVRIL 2016

[email protected]  https://github.com/leverdeterre

AU SOMMAIRE

QuickActionsPeek and PopPeek Quick Actions

2

COMMENT ? QUI ? QUAND ?

COMMENT, QUI, QUAND?

• CommentUne couche supplémentaire…iPhone 6S (7.1mm contre 6.9mm)

• Les appareilsiPhone 6S, 6S Plus

• Version d’OSiOS9

4

QUICK ACTIONS

QUICK ACTIONS

Pression sur l’icône de l’application

4 items maximum

Ces items peuvent être statiques ou dynamiques

Le but : aller plus vite et recentrer l’utilisateur !

6

QUICK ACTIONS > STATIQUES

info.plist

7

UIApplicationShortcutItemType la référence unique qu’aura l’action (ex: com.jmo.add.to.favorite)

UIApplicationShortcutItemTitle le titre de l’action

UIApplicationShortcutItemSubtitle le sous titre de l’action

UIApplicationShortcutItemIconType une valeur de l’énumération UIApplicationShortcutIconType

UIApplicationShortcutItemIconFile une image que l’on souhaite utiliser(35x35, 1 couleur)

UIApplicationShortcutItemUserInfo un dictionnaire pour des informations complémentaires.

QUICK ACTIONS > STATIQUES

info.plist

8

UIApplicationShortcutItemType la référence unique qu’aura l’action (ex: com.jmo.add.to.favorite)

UIApplicationShortcutItemTitle le titre de l’action

UIApplicationShortcutItemSubtitle le sous titre de l’action

UIApplicationShortcutItemIconType une valeur de l’énumération UIApplicationShortcutIconType

UIApplicationShortcutItemIconFile une image que l’on souhaite utiliser(35x35, 1 couleur)

UIApplicationShortcutItemUserInfo un dictionnaire pour des informations complémentaires.

https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html

QUICK ACTIONS > STATIQUES > EXEMPLE DE PLIST

• info.plist

9

QUICK ACTIONS > DYNAMIQUES > UIAPPLICATION

10

@interface  UIApplication  (UIShortcutItems)  //  Register  shortcuts  to  display  on  the  home  screen,  or  retrieve  currently  registered  shortcuts.  @property  (nullable,  nonatomic,  copy)  NSArray<UIApplicationShortcutItem  *>  *shortcutItems  NS_AVAILABLE_IOS(9_0)  __TVOS_PROHIBITED;  @end  

[UIApplication  sharedApplication].shortcutItems  =  @[myAwesomeShortcutItem];

UIApplicationShortcutItem

QUICK ACTIONS > DYNAMIQUES > SHORTCUTITEMS

11

@interface  UIApplicationShortcutItem  :  NSObject  <NSCopying,  NSMutableCopying>  -­‐  (instancetype)init  NS_UNAVAILABLE;  

-­‐  (instancetype)initWithType:(NSString  *)type                                                            localizedTitle:(NSString  *)localizedTitle                                                  localizedSubtitle:(nullable  NSString  *)localizedSubtitle                                                                                            icon:(nullable  UIApplicationShortcutIcon  *)icon                                                                              userInfo:(nullable  NSDictionary  *)userInfo  NS_DESIGNATED_INITIALIZER;  

-­‐  (instancetype)initWithType:(NSString  *)type  localizedTitle:(NSString  *)localizedTitle;  @end  

QUICK ACTIONS > DYNAMIQUES > SHORTCUTITEMS

12

@interface  UIApplicationShortcutItem  :  NSObject  <NSCopying,  NSMutableCopying>  -­‐  (instancetype)init  NS_UNAVAILABLE;  

-­‐  (instancetype)initWithType:(NSString  *)type                                                            localizedTitle:(NSString  *)localizedTitle                                                  localizedSubtitle:(nullable  NSString  *)localizedSubtitle                                                                                            icon:(nullable  UIApplicationShortcutIcon  *)icon                                                                              userInfo:(nullable  NSDictionary  *)userInfo  NS_DESIGNATED_INITIALIZER;  

-­‐  (instancetype)initWithType:(NSString  *)type  localizedTitle:(NSString  *)localizedTitle;  @end  

QUICK ACTIONS > DYNAMIQUES > SHORTCUTITEMS > INIT

13

-­‐  (instancetype)initWithType:(NSString  *)type                                                            localizedTitle:(NSString  *)localizedTitle                                                  localizedSubtitle:(nullable  NSString  *)localizedSubtitle                                                                                            icon:(nullable  UIApplicationShortcutIcon  *)icon                                                                              userInfo:(nullable  NSDictionary  *)userInfo  NS_DESIGNATED_INITIALIZER;  

QUICK ACTIONS > DYNAMIQUES > SHORTCUTITEMS > INIT

14

-­‐  (instancetype)initWithType:(NSString  *)type                                                            localizedTitle:(NSString  *)localizedTitle                                                  localizedSubtitle:(nullable  NSString  *)localizedSubtitle                                                                                            icon:(nullable  UIApplicationShortcutIcon  *)icon                                                                              userInfo:(nullable  NSDictionary  *)userInfo  NS_DESIGNATED_INITIALIZER;  

QUICK ACTIONS > INTERCEPTION !

15

// Called when the user activates your application by selecting a shortcut on the home screen, // except when -application:willFinishLaunchingWithOptions: or -application:didFinishLaunchingWithOptions returns NO. -(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler;

QUICK ACTIONS > INTERCEPTION !

16

// Called when the user activates your application by selecting a shortcut on the home screen, // except when -application:willFinishLaunchingWithOptions: or -application:didFinishLaunchingWithOptions returns NO. -(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler;

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions;

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions;

UIKIT_EXTERN NSString *const UIApplicationLaunchOptionsShortcutItemKey

QUICK ACTIONS > ASTUCES > 1

• Pas de simulateur, il faut un iPhone 6S ou 6S

• https://github.com/DeskConnect/SBShortcutMenuSimulator pour permettre de simuler les QuickActions.

17

QUICK ACTIONS > ASTUCES > 2

• Internationalisation !

• En utilisant l’InfoPlist.strings, UIApplicationShortcutItemTitle contiendra la clé de traduction.

18

QUICK ACTIONS > ASTUCES > 3

• Attention aux icônes systèmes, car Apple en rajoute !

19

typedef  NS_ENUM(NSInteger,  UIApplicationShortcutIconType)  {          UIApplicationShortcutIconTypeCompose,          UIApplicationShortcutIconTypePlay,          UIApplicationShortcutIconTypePause,          UIApplicationShortcutIconTypeAdd,          UIApplicationShortcutIconTypeLocation,          UIApplicationShortcutIconTypeSearch,          UIApplicationShortcutIconTypeShare,          UIApplicationShortcutIconTypeProhibit              NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeContact                NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeHome                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeMarkLocation      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeFavorite              NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeLove                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeCloud                    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeInvitation          NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeConfirmation      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeMail                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeMessage                NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeDate                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeTime                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeCapturePhoto      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeCaptureVideo      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeTask                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeTaskCompleted    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeAlarm                    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeBookmark              NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeShuffle                NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeAudio                    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeUpdate                  NS_ENUM_AVAILABLE_IOS(9_1)  }  NS_ENUM_AVAILABLE_IOS(9_0);  

QUICK ACTIONS > ASTUCES > 3

• Attention aux icônes systèmes, car Apple en rajoute !

20

typedef  NS_ENUM(NSInteger,  UIApplicationShortcutIconType)  {          UIApplicationShortcutIconTypeCompose,          UIApplicationShortcutIconTypePlay,          UIApplicationShortcutIconTypePause,          UIApplicationShortcutIconTypeAdd,          UIApplicationShortcutIconTypeLocation,          UIApplicationShortcutIconTypeSearch,          UIApplicationShortcutIconTypeShare,          UIApplicationShortcutIconTypeProhibit              NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeContact                NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeHome                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeMarkLocation      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeFavorite              NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeLove                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeCloud                    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeInvitation          NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeConfirmation      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeMail                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeMessage                NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeDate                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeTime                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeCapturePhoto      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeCaptureVideo      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeTask                      NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeTaskCompleted    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeAlarm                    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeBookmark              NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeShuffle                NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeAudio                    NS_ENUM_AVAILABLE_IOS(9_1),          UIApplicationShortcutIconTypeUpdate                  NS_ENUM_AVAILABLE_IOS(9_1)  }  NS_ENUM_AVAILABLE_IOS(9_0);  

-­‐  Xcode  7.1  pour  compiler  !    -­‐  iOS9.1  !

QUICK  ACTIONS  >  ASTUCES  >  4

• Les icônes 35x35, 1 couleur … sauf pour les contacts

21

@interface  UIApplicationShortcutIcon  (ContactsUI)  

+  (instancetype)iconWithContact:(CNContact  *)contact;  

@end  

PEEK AND POP

PEEK  AND  POP

• Dans l’application,• Pression sur un « call to action » à l’écran,• Prévisualisation,• Affichage d’un écran final.

23

PEEK  AND  POP

Prévisualisation du détail

24

PEEK  AND  POP

Affichage du détail plein écran

25

PEEK  AND  POP  :  API

Une catégorie sur UIViewController (UIViewControllerPreviewingRegistration)

Deux protocoles UIViewControllerPreviewingDelegate, UIViewControllerPreviewing

26

PEEK  AND  POP  :  API  >  PREVIEWINGREGISTRATION

La catégorie sur UIViewController (UIViewControllerPreviewingRegistration)

On enregistre/désabonne notre ViewController pour gérer la prévisualisation.

27

@interface  UIViewController  (UIViewControllerPreviewingRegistration)  

//  Registers  a  view  controller  to  participate  with  3D  Touch  preview  (peek)  and  commit  (pop).  -­‐  (id  <UIViewControllerPreviewing>)registerForPreviewingWithDelegate:(id<UIViewControllerPreviewingDelegate>)delegate  sourceView:(UIView  *)sourceView  NS_AVAILABLE_IOS(9_0);  -­‐  (void)unregisterForPreviewingWithContext:(id  <UIViewControllerPreviewing>)previewing  NS_AVAILABLE_IOS(9_0);  

@end

PEEK  AND  POP  :  API  >  PREVISUALISER

Le protocole UIViewControllerPreviewing est un protocole informatif,

28

@protocol  UIViewControllerPreviewing  <NSObject>  

//  This  gesture  can  be  used  to  cause  the  previewing  presentation  to  wait  until  one  of  your  gestures  fails  or  to  allow  simultaneous  recognition  during  the  initial  phase  of  the  preview  presentation.  @property  (nonatomic,  readonly)  UIGestureRecognizer  *previewingGestureRecognizerForFailureRelationship  NS_AVAILABLE_IOS(9_0);  

@property  (nonatomic,  readonly)  id<UIViewControllerPreviewingDelegate>  delegate  NS_AVAILABLE_IOS(9_0);  @property  (nonatomic,  readonly)  UIView  *sourceView  NS_AVAILABLE_IOS(9_0);  

//  This  rect  will  be  set  to  the  bounds  of  sourceView  before  each  call  to  //  -­‐previewingContext:viewControllerForLocation:  

@property  (nonatomic)  CGRect  sourceRect  NS_AVAILABLE_IOS(9_0);  

@end

PEEK  AND  POP  :  API  >  PREVISUALISER

Le protocole UIViewControllerPreviewing est un protocole informatif,

29

@protocol  UIViewControllerPreviewing  <NSObject>  

//  This  gesture  can  be  used  to  cause  the  previewing  presentation  to  wait  until  one  of  your  gestures  fails  or  to  allow  simultaneous  recognition  during  the  initial  phase  of  the  preview  presentation.  @property  (nonatomic,  readonly)  UIGestureRecognizer  *previewingGestureRecognizerForFailureRelationship  NS_AVAILABLE_IOS(9_0);  

@property  (nonatomic,  readonly)  id<UIViewControllerPreviewingDelegate>  delegate  NS_AVAILABLE_IOS(9_0);  @property  (nonatomic,  readonly)  UIView  *sourceView  NS_AVAILABLE_IOS(9_0);  

//  This  rect  will  be  set  to  the  bounds  of  sourceView  before  each  call  to  //  -­‐previewingContext:viewControllerForLocation:  

@property  (nonatomic)  CGRect  sourceRect  NS_AVAILABLE_IOS(9_0);  

@end

PEEK  AND  POP  :  API  >  PREVISUALISER

L’implémentation du protocole UIViewControllerPreviewingDelegateLe système nous délègue :

La construction du contrôleur pour visualiser le détail (le retour du protocole), Trouver la zone à mettre en avant (mise à jour du previewingContext.sourceRect)

30

NS_CLASS_AVAILABLE_IOS(9_0)  @protocol  UIViewControllerPreviewingDelegate  <NSObject>  

//  If  you  return  nil,  a  preview  presentation  will  not  be  performed  -­‐  (nullable  UIViewController  *)previewingContext:(id  <UIViewControllerPreviewing>)previewingContext  viewControllerForLocation:(CGPoint)location  NS_AVAILABLE_IOS(9_0);  

@end  

PEEK  AND  POP  :  API  >  «  POPER  »

L’implémentation du protocole UIViewControllerPreviewingDelegate.Le système nous délègue la finalisation la transaction.

On peut : ne rien faire, pousser le même contrôleur, pousser un autre contrôleur,faire une autre action.

31

NS_CLASS_AVAILABLE_IOS(9_0)  @protocol  UIViewControllerPreviewingDelegate  <NSObject>  

-­‐  (void)previewingContext:(id  <UIViewControllerPreviewing>)previewingContext  commitViewController:(UIViewController  *)viewControllerToCommit  NS_AVAILABLE_IOS(9_0);  

@end

PEEK  AND  POP  :  API  >  «  POPER  »

L’implémentation du protocole UIViewControllerPreviewingDelegate.Le système nous délègue la finalisation la transaction.

On peut : ne rien faire, pousser le même contrôleur, pousser un autre contrôleur,faire une autre action.

32

NS_CLASS_AVAILABLE_IOS(9_0)  @protocol  UIViewControllerPreviewingDelegate  <NSObject>  

-­‐  (void)previewingContext:(id  <UIViewControllerPreviewing>)previewingContext  commitViewController:(UIViewController  *)viewControllerToCommit  NS_AVAILABLE_IOS(9_0);  

@end

PEEK  AND  POP  :  API  >  POUR  FAIRE  SIMPLE  !

33

NS_CLASS_AVAILABLE_IOS(9_0)  @protocol  UIViewControllerPreviewingDelegate  <NSObject>  

//  If  you  return  nil,  a  preview  presentation  will  not  be  performed  -­‐  (nullable  UIViewController  *)previewingContext:(id  <UIViewControllerPreviewing>)previewingContext  viewControllerForLocation:(CGPoint)location  NS_AVAILABLE_IOS(9_0);  

-­‐  (void)previewingContext:(id  <UIViewControllerPreviewing>)previewingContext  commitViewController:(UIViewController  *)viewControllerToCommit  NS_AVAILABLE_IOS(9_0);  

@end  

Peek

Pop

PEEK  AND  POP  :  API  >  PEEK  QUICK  ACTIONS

Le contrôleur « peeké » peut exposer des actions en faisant un geste vers le haut.

Les actions peuvent être regroupées sous forme de blocs.

34

PEEK  AND  POP  :  API  >  PEEK  QUICK  ACTIONS

35

Une catégorie « anonyme » sur UIViewController ()

@protocol  UIPreviewActionItem;  @interface  UIViewController  ()  -­‐  (NSArray  <id  <UIPreviewActionItem>>  *)previewActionItems  NS_AVAILABLE_IOS(9_0);  @end  

NS_CLASS_AVAILABLE_IOS(9_0)  @protocol  UIPreviewActionItem  <NSObject>  @property(nonatomic,  copy,  readonly)  NSString  *title;  @end  

NS_CLASS_AVAILABLE_IOS(9_0)  @interface  UIPreviewAction  :  NSObject  <NSCopying,UIPreviewActionItem>  @end  

NS_CLASS_AVAILABLE_IOS(9_0)  @interface  UIPreviewActionGroup  :  NSObject  <NSCopying,UIPreviewActionItem>  @end

PEEK  AND  POP  :  API  >  DETECTION  DES  APPAREILS  ÉLIGIBLES

La propriété forceTouchCapability sur UITraitCollectionAttention aux appels d’API, forceTouchCapability (iOS9), UITraitCollection (iOS8)

36

typedef NS_ENUM(NSInteger, UIForceTouchCapability) { UIForceTouchCapabilityUnknown = 0, UIForceTouchCapabilityUnavailable = 1, UIForceTouchCapabilityAvailable = 2 };

NS_CLASS_AVAILABLE_IOS(8_0) @interface UITraitCollection : NSObject <NSCopying, NSSecureCoding> … @property (nonatomic, readonly) UIForceTouchCapability forceTouchCapability NS_AVAILABLE_IOS(9_0); // unspecified: UIForceTouchCapabilityUnknown … @end

PEEK  AND  POP  :  API  >  WEBVIEW

UIWebView et WKWebViewallowLinks = YES

37

PEEK  AND  POP  :  API  >  STORYBOARD  

Pas de codeXcode 7.1

38

CONCLUSION

Mise en place peu coûteuse

Amélioration de l'interactivité des apps

Pas testable sur simulateur

iOS9 et iPhone 6S (Plus)

40

REFERENCES

Documentation  techniques  https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/Adopting3DTouchOniPhone/index.html#//

apple_ref/doc/uid/TP40016543-­‐CH1-­‐SW1  

Guidelines  graphiques  https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/3DTouch.html#//apple_ref/doc/

uid/TP40006556-­‐CH71  

Tutoriels  Quick  Actions  http://www.stringcode.co.uk/add-­‐ios-­‐9s-­‐quick-­‐actions-­‐shortcut-­‐support-­‐in-­‐15-­‐minutes-­‐right-­‐now/  Peek  and  Pop  http://pinkstone.co.uk/how-­‐to-­‐use-­‐3d-­‐touch-­‐in-­‐ios-­‐9-­‐part-­‐1-­‐peek-­‐and-­‐pop/  

       http://krakendev.io/peek-­‐pop/  

3D  Touch  http://engineering.instagram.com/posts/465414923641286/lessons-­‐learned-­‐with-­‐3D-­‐touch  

41