cocoaheads montpellier meetup : 3d touch for ios
TRANSCRIPT
3DTOUCHCOCOAHEADS - MONTPELLIER - 14 AVRIL 2016
[email protected] https://github.com/leverdeterre
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
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 > 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
• Dans l’application,• Pression sur un « call to action » à l’écran,• Prévisualisation,• Affichage d’un écran final.
23
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
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