├── 3DTouchSample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── RichardLeung.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── 3DTouchSample.xcscheme │ └── xcschememanagement.plist ├── 3DTouchSample ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── Icon120@2x.png │ ├── Contents.json │ ├── 美国队长.imageset │ │ ├── Contents.json │ │ └── 美国队长.jpg │ ├── 钢铁侠.imageset │ │ ├── Contents.json │ │ └── 钢铁侠.jpg │ ├── 雷神.imageset │ │ ├── Contents.json │ │ └── 雷神.jpg │ └── 黑寡妇.imageset │ │ ├── Contents.json │ │ └── 黑寡妇.jpg ├── Base.lproj │ └── LaunchScreen.storyboard ├── DetailViewController.h ├── DetailViewController.m ├── Info.plist ├── ViewController.h ├── ViewController.m ├── image │ ├── demo1.gif │ ├── demo2.gif │ ├── preview.jpg │ └── shortcut.jpg └── main.m └── README.md /3DTouchSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 90E060B61BE4FF1F006F58DB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E060B51BE4FF1F006F58DB /* main.m */; }; 11 | 90E060B91BE4FF1F006F58DB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E060B81BE4FF1F006F58DB /* AppDelegate.m */; }; 12 | 90E060BC1BE4FF1F006F58DB /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E060BB1BE4FF1F006F58DB /* ViewController.m */; }; 13 | 90E060C11BE4FF1F006F58DB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 90E060C01BE4FF1F006F58DB /* Assets.xcassets */; }; 14 | 90E060C41BE4FF1F006F58DB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90E060C21BE4FF1F006F58DB /* LaunchScreen.storyboard */; }; 15 | 90E060CD1BE4FF8E006F58DB /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E060CC1BE4FF8E006F58DB /* DetailViewController.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 90E060B11BE4FF1F006F58DB /* 3DTouchSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 3DTouchSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 90E060B51BE4FF1F006F58DB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 21 | 90E060B71BE4FF1F006F58DB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 22 | 90E060B81BE4FF1F006F58DB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 23 | 90E060BA1BE4FF1F006F58DB /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 24 | 90E060BB1BE4FF1F006F58DB /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 25 | 90E060C01BE4FF1F006F58DB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26 | 90E060C31BE4FF1F006F58DB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 27 | 90E060C51BE4FF1F006F58DB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | 90E060CB1BE4FF8E006F58DB /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; 29 | 90E060CC1BE4FF8E006F58DB /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; 30 | /* End PBXFileReference section */ 31 | 32 | /* Begin PBXFrameworksBuildPhase section */ 33 | 90E060AE1BE4FF1F006F58DB /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 90E060A81BE4FF1F006F58DB = { 44 | isa = PBXGroup; 45 | children = ( 46 | 90E060B31BE4FF1F006F58DB /* 3DTouchSample */, 47 | 90E060B21BE4FF1F006F58DB /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | 90E060B21BE4FF1F006F58DB /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 90E060B11BE4FF1F006F58DB /* 3DTouchSample.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | 90E060B31BE4FF1F006F58DB /* 3DTouchSample */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 90E060B71BE4FF1F006F58DB /* AppDelegate.h */, 63 | 90E060B81BE4FF1F006F58DB /* AppDelegate.m */, 64 | 90E060BA1BE4FF1F006F58DB /* ViewController.h */, 65 | 90E060BB1BE4FF1F006F58DB /* ViewController.m */, 66 | 90E060CB1BE4FF8E006F58DB /* DetailViewController.h */, 67 | 90E060CC1BE4FF8E006F58DB /* DetailViewController.m */, 68 | 90E060C01BE4FF1F006F58DB /* Assets.xcassets */, 69 | 90E060C21BE4FF1F006F58DB /* LaunchScreen.storyboard */, 70 | 90E060C51BE4FF1F006F58DB /* Info.plist */, 71 | 90E060B41BE4FF1F006F58DB /* Supporting Files */, 72 | ); 73 | path = 3DTouchSample; 74 | sourceTree = ""; 75 | }; 76 | 90E060B41BE4FF1F006F58DB /* Supporting Files */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 90E060B51BE4FF1F006F58DB /* main.m */, 80 | ); 81 | name = "Supporting Files"; 82 | sourceTree = ""; 83 | }; 84 | /* End PBXGroup section */ 85 | 86 | /* Begin PBXNativeTarget section */ 87 | 90E060B01BE4FF1F006F58DB /* 3DTouchSample */ = { 88 | isa = PBXNativeTarget; 89 | buildConfigurationList = 90E060C81BE4FF1F006F58DB /* Build configuration list for PBXNativeTarget "3DTouchSample" */; 90 | buildPhases = ( 91 | 90E060AD1BE4FF1F006F58DB /* Sources */, 92 | 90E060AE1BE4FF1F006F58DB /* Frameworks */, 93 | 90E060AF1BE4FF1F006F58DB /* Resources */, 94 | ); 95 | buildRules = ( 96 | ); 97 | dependencies = ( 98 | ); 99 | name = 3DTouchSample; 100 | productName = 3DTouchSample; 101 | productReference = 90E060B11BE4FF1F006F58DB /* 3DTouchSample.app */; 102 | productType = "com.apple.product-type.application"; 103 | }; 104 | /* End PBXNativeTarget section */ 105 | 106 | /* Begin PBXProject section */ 107 | 90E060A91BE4FF1F006F58DB /* Project object */ = { 108 | isa = PBXProject; 109 | attributes = { 110 | LastUpgradeCheck = 0710; 111 | ORGANIZATIONNAME = RL; 112 | TargetAttributes = { 113 | 90E060B01BE4FF1F006F58DB = { 114 | CreatedOnToolsVersion = 7.1; 115 | }; 116 | }; 117 | }; 118 | buildConfigurationList = 90E060AC1BE4FF1F006F58DB /* Build configuration list for PBXProject "3DTouchSample" */; 119 | compatibilityVersion = "Xcode 3.2"; 120 | developmentRegion = English; 121 | hasScannedForEncodings = 0; 122 | knownRegions = ( 123 | en, 124 | Base, 125 | ); 126 | mainGroup = 90E060A81BE4FF1F006F58DB; 127 | productRefGroup = 90E060B21BE4FF1F006F58DB /* Products */; 128 | projectDirPath = ""; 129 | projectRoot = ""; 130 | targets = ( 131 | 90E060B01BE4FF1F006F58DB /* 3DTouchSample */, 132 | ); 133 | }; 134 | /* End PBXProject section */ 135 | 136 | /* Begin PBXResourcesBuildPhase section */ 137 | 90E060AF1BE4FF1F006F58DB /* Resources */ = { 138 | isa = PBXResourcesBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | 90E060C41BE4FF1F006F58DB /* LaunchScreen.storyboard in Resources */, 142 | 90E060C11BE4FF1F006F58DB /* Assets.xcassets in Resources */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | /* End PBXResourcesBuildPhase section */ 147 | 148 | /* Begin PBXSourcesBuildPhase section */ 149 | 90E060AD1BE4FF1F006F58DB /* Sources */ = { 150 | isa = PBXSourcesBuildPhase; 151 | buildActionMask = 2147483647; 152 | files = ( 153 | 90E060BC1BE4FF1F006F58DB /* ViewController.m in Sources */, 154 | 90E060B91BE4FF1F006F58DB /* AppDelegate.m in Sources */, 155 | 90E060B61BE4FF1F006F58DB /* main.m in Sources */, 156 | 90E060CD1BE4FF8E006F58DB /* DetailViewController.m in Sources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXSourcesBuildPhase section */ 161 | 162 | /* Begin PBXVariantGroup section */ 163 | 90E060C21BE4FF1F006F58DB /* LaunchScreen.storyboard */ = { 164 | isa = PBXVariantGroup; 165 | children = ( 166 | 90E060C31BE4FF1F006F58DB /* Base */, 167 | ); 168 | name = LaunchScreen.storyboard; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXVariantGroup section */ 172 | 173 | /* Begin XCBuildConfiguration section */ 174 | 90E060C61BE4FF1F006F58DB /* Debug */ = { 175 | isa = XCBuildConfiguration; 176 | buildSettings = { 177 | ALWAYS_SEARCH_USER_PATHS = NO; 178 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 179 | CLANG_CXX_LIBRARY = "libc++"; 180 | CLANG_ENABLE_MODULES = YES; 181 | CLANG_ENABLE_OBJC_ARC = YES; 182 | CLANG_WARN_BOOL_CONVERSION = YES; 183 | CLANG_WARN_CONSTANT_CONVERSION = YES; 184 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 185 | CLANG_WARN_EMPTY_BODY = YES; 186 | CLANG_WARN_ENUM_CONVERSION = YES; 187 | CLANG_WARN_INT_CONVERSION = YES; 188 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 189 | CLANG_WARN_UNREACHABLE_CODE = YES; 190 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 191 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 192 | COPY_PHASE_STRIP = NO; 193 | DEBUG_INFORMATION_FORMAT = dwarf; 194 | ENABLE_STRICT_OBJC_MSGSEND = YES; 195 | ENABLE_TESTABILITY = YES; 196 | GCC_C_LANGUAGE_STANDARD = gnu99; 197 | GCC_DYNAMIC_NO_PIC = NO; 198 | GCC_NO_COMMON_BLOCKS = YES; 199 | GCC_OPTIMIZATION_LEVEL = 0; 200 | GCC_PREPROCESSOR_DEFINITIONS = ( 201 | "DEBUG=1", 202 | "$(inherited)", 203 | ); 204 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 205 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 206 | GCC_WARN_UNDECLARED_SELECTOR = YES; 207 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 208 | GCC_WARN_UNUSED_FUNCTION = YES; 209 | GCC_WARN_UNUSED_VARIABLE = YES; 210 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 211 | MTL_ENABLE_DEBUG_INFO = YES; 212 | ONLY_ACTIVE_ARCH = YES; 213 | SDKROOT = iphoneos; 214 | TARGETED_DEVICE_FAMILY = "1,2"; 215 | }; 216 | name = Debug; 217 | }; 218 | 90E060C71BE4FF1F006F58DB /* Release */ = { 219 | isa = XCBuildConfiguration; 220 | buildSettings = { 221 | ALWAYS_SEARCH_USER_PATHS = NO; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 223 | CLANG_CXX_LIBRARY = "libc++"; 224 | CLANG_ENABLE_MODULES = YES; 225 | CLANG_ENABLE_OBJC_ARC = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_CONSTANT_CONVERSION = YES; 228 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 229 | CLANG_WARN_EMPTY_BODY = YES; 230 | CLANG_WARN_ENUM_CONVERSION = YES; 231 | CLANG_WARN_INT_CONVERSION = YES; 232 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 233 | CLANG_WARN_UNREACHABLE_CODE = YES; 234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 235 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 236 | COPY_PHASE_STRIP = NO; 237 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 238 | ENABLE_NS_ASSERTIONS = NO; 239 | ENABLE_STRICT_OBJC_MSGSEND = YES; 240 | GCC_C_LANGUAGE_STANDARD = gnu99; 241 | GCC_NO_COMMON_BLOCKS = YES; 242 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 243 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 244 | GCC_WARN_UNDECLARED_SELECTOR = YES; 245 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 246 | GCC_WARN_UNUSED_FUNCTION = YES; 247 | GCC_WARN_UNUSED_VARIABLE = YES; 248 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 249 | MTL_ENABLE_DEBUG_INFO = NO; 250 | SDKROOT = iphoneos; 251 | TARGETED_DEVICE_FAMILY = "1,2"; 252 | VALIDATE_PRODUCT = YES; 253 | }; 254 | name = Release; 255 | }; 256 | 90E060C91BE4FF1F006F58DB /* Debug */ = { 257 | isa = XCBuildConfiguration; 258 | buildSettings = { 259 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 260 | INFOPLIST_FILE = 3DTouchSample/Info.plist; 261 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 262 | PRODUCT_BUNDLE_IDENTIFIER = com.richard.3DTouchSample; 263 | PRODUCT_NAME = "$(TARGET_NAME)"; 264 | }; 265 | name = Debug; 266 | }; 267 | 90E060CA1BE4FF1F006F58DB /* Release */ = { 268 | isa = XCBuildConfiguration; 269 | buildSettings = { 270 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 271 | INFOPLIST_FILE = 3DTouchSample/Info.plist; 272 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 273 | PRODUCT_BUNDLE_IDENTIFIER = com.richard.3DTouchSample; 274 | PRODUCT_NAME = "$(TARGET_NAME)"; 275 | }; 276 | name = Release; 277 | }; 278 | /* End XCBuildConfiguration section */ 279 | 280 | /* Begin XCConfigurationList section */ 281 | 90E060AC1BE4FF1F006F58DB /* Build configuration list for PBXProject "3DTouchSample" */ = { 282 | isa = XCConfigurationList; 283 | buildConfigurations = ( 284 | 90E060C61BE4FF1F006F58DB /* Debug */, 285 | 90E060C71BE4FF1F006F58DB /* Release */, 286 | ); 287 | defaultConfigurationIsVisible = 0; 288 | defaultConfigurationName = Release; 289 | }; 290 | 90E060C81BE4FF1F006F58DB /* Build configuration list for PBXNativeTarget "3DTouchSample" */ = { 291 | isa = XCConfigurationList; 292 | buildConfigurations = ( 293 | 90E060C91BE4FF1F006F58DB /* Debug */, 294 | 90E060CA1BE4FF1F006F58DB /* Release */, 295 | ); 296 | defaultConfigurationIsVisible = 0; 297 | defaultConfigurationName = Release; 298 | }; 299 | /* End XCConfigurationList section */ 300 | }; 301 | rootObject = 90E060A91BE4FF1F006F58DB /* Project object */; 302 | } 303 | -------------------------------------------------------------------------------- /3DTouchSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /3DTouchSample.xcodeproj/xcuserdata/RichardLeung.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /3DTouchSample.xcodeproj/xcuserdata/RichardLeung.xcuserdatad/xcschemes/3DTouchSample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /3DTouchSample.xcodeproj/xcuserdata/RichardLeung.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | 3DTouchSample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 90E060B01BE4FF1F006F58DB 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /3DTouchSample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /3DTouchSample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @property(nonatomic,strong)ViewController *viewController; 15 | 16 | @end 17 | 18 | @implementation AppDelegate 19 | 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | // Override point for customization after application launch. 23 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 24 | self.window.backgroundColor =[UIColor whiteColor]; 25 | _viewController =[[ViewController alloc]init]; 26 | UINavigationController *navigationController =[[UINavigationController alloc]initWithRootViewController:_viewController]; 27 | self.window.rootViewController =navigationController; 28 | [self.window makeKeyAndVisible]; 29 | 30 | //动态加载自定义的ShortcutItem 31 | if (application.shortcutItems.count == 0) { 32 | UIMutableApplicationShortcutItem *itemThor =[[UIMutableApplicationShortcutItem alloc]initWithType:[NSString stringWithFormat:@"%@.second",[[NSBundle mainBundle] bundleIdentifier]] localizedTitle:@"雷神" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeLocation] userInfo:nil]; 33 | UIMutableApplicationShortcutItem *itemBlack =[[UIMutableApplicationShortcutItem alloc]initWithType:[NSString stringWithFormat:@"%@.third",[[NSBundle mainBundle] bundleIdentifier]] localizedTitle:@"黑寡妇" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeLocation] userInfo:nil]; 34 | UIMutableApplicationShortcutItem *itemCaptain =[[UIMutableApplicationShortcutItem alloc]initWithType:[NSString stringWithFormat:@"%@.fourth",[[NSBundle mainBundle] bundleIdentifier]] localizedTitle:@"美国队长" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeLocation] userInfo:nil]; 35 | application.shortcutItems = @[itemBlack,itemCaptain,itemThor]; 36 | } 37 | return YES; 38 | } 39 | 40 | - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler{ 41 | [_viewController.navigationController popToRootViewControllerAnimated:NO]; 42 | _viewController.shortcutName =shortcutItem.localizedTitle; 43 | [[NSNotificationCenter defaultCenter] postNotificationName:@"ShortCut" object:nil]; 44 | } 45 | 46 | 47 | 48 | - (void)applicationWillResignActive:(UIApplication *)application { 49 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 50 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 51 | } 52 | 53 | - (void)applicationDidEnterBackground:(UIApplication *)application { 54 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 55 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 56 | //[RLGlobal shareInstance].shortcutStatus =RLShortcutStatusNone; 57 | _viewController.shortcutName =nil; 58 | } 59 | 60 | - (void)applicationWillEnterForeground:(UIApplication *)application { 61 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 62 | } 63 | 64 | - (void)applicationDidBecomeActive:(UIApplication *)application { 65 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 66 | } 67 | 68 | - (void)applicationWillTerminate:(UIApplication *)application { 69 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon120@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "idiom" : "iphone", 31 | "size" : "60x60", 32 | "scale" : "3x" 33 | }, 34 | { 35 | "idiom" : "ipad", 36 | "size" : "29x29", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "idiom" : "ipad", 41 | "size" : "29x29", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "idiom" : "ipad", 46 | "size" : "40x40", 47 | "scale" : "1x" 48 | }, 49 | { 50 | "idiom" : "ipad", 51 | "size" : "40x40", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "idiom" : "ipad", 56 | "size" : "76x76", 57 | "scale" : "1x" 58 | }, 59 | { 60 | "idiom" : "ipad", 61 | "size" : "76x76", 62 | "scale" : "2x" 63 | } 64 | ], 65 | "info" : { 66 | "version" : 1, 67 | "author" : "xcode" 68 | } 69 | } -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/AppIcon.appiconset/Icon120@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/Assets.xcassets/AppIcon.appiconset/Icon120@2x.png -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/美国队长.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "美国队长.jpg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/美国队长.imageset/美国队长.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/Assets.xcassets/美国队长.imageset/美国队长.jpg -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/钢铁侠.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "钢铁侠.jpg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/钢铁侠.imageset/钢铁侠.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/Assets.xcassets/钢铁侠.imageset/钢铁侠.jpg -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/雷神.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "雷神.jpg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/雷神.imageset/雷神.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/Assets.xcassets/雷神.imageset/雷神.jpg -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/黑寡妇.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "黑寡妇.jpg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /3DTouchSample/Assets.xcassets/黑寡妇.imageset/黑寡妇.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/Assets.xcassets/黑寡妇.imageset/黑寡妇.jpg -------------------------------------------------------------------------------- /3DTouchSample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /3DTouchSample/DetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.h 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DetailViewController : UIViewController 12 | 13 | - (instancetype)initWithTitle:(NSString *)title; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /3DTouchSample/DetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.m 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import "DetailViewController.h" 10 | 11 | @interface DetailViewController () 12 | 13 | @property(nonatomic,strong)UIImageView *imageViewShow; 14 | 15 | @end 16 | 17 | @implementation DetailViewController 18 | 19 | - (instancetype)initWithTitle:(NSString *)title 20 | { 21 | self = [super init]; 22 | if (self) { 23 | self.title =title; 24 | } 25 | return self; 26 | } 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | self.view.backgroundColor =[UIColor whiteColor]; 31 | UIImage *image =[UIImage imageNamed:self.title]; 32 | _imageViewShow =[[UIImageView alloc]initWithImage:image]; 33 | _imageViewShow.frame =self.view.bounds; 34 | [self.view addSubview:_imageViewShow]; 35 | } 36 | 37 | - (NSArray > *)previewActionItems 38 | { 39 | UIPreviewAction *action = [UIPreviewAction actionWithTitle:@"赞" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { 40 | 41 | }]; 42 | return @[action]; 43 | } 44 | 45 | - (void)didReceiveMemoryWarning { 46 | [super didReceiveMemoryWarning]; 47 | // Dispose of any resources that can be recreated. 48 | } 49 | 50 | /* 51 | #pragma mark - Navigation 52 | 53 | // In a storyboard-based application, you will often want to do a little preparation before navigation 54 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 55 | // Get the new view controller using [segue destinationViewController]. 56 | // Pass the selected object to the new view controller. 57 | } 58 | */ 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /3DTouchSample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIApplicationShortcutItems 26 | 27 | 28 | UIApplicationShortcutItemIconType 29 | UIApplicationShortcutIconTypeLocation 30 | UIApplicationShortcutItemTitle 31 | 钢铁侠 32 | UIApplicationShortcutItemType 33 | $(PRODUCT_BUNDLE_IDENTIFIER).first 34 | UIApplicationShortcutItemUserInfo 35 | 36 | firstShortcutKey 37 | firstShortcutValue 38 | 39 | 40 | 41 | UILaunchStoryboardName 42 | LaunchScreen 43 | UIRequiredDeviceCapabilities 44 | 45 | armv7 46 | 47 | UISupportedInterfaceOrientations 48 | 49 | UIInterfaceOrientationPortrait 50 | UIInterfaceOrientationLandscapeLeft 51 | UIInterfaceOrientationLandscapeRight 52 | 53 | UISupportedInterfaceOrientations~ipad 54 | 55 | UIInterfaceOrientationPortrait 56 | UIInterfaceOrientationPortraitUpsideDown 57 | UIInterfaceOrientationLandscapeLeft 58 | UIInterfaceOrientationLandscapeRight 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /3DTouchSample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @property(nonatomic,strong)NSString *shortcutName; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /3DTouchSample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "DetailViewController.h" 11 | 12 | @interface ViewController () 13 | 14 | @property(nonatomic,strong)UITableView *tableViewList; 15 | @property(nonatomic,strong)NSArray *arrayData; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)dealloc 22 | { 23 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 24 | } 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | // Do any additional setup after loading the view, typically from a nib. 29 | [self initDefaultData]; 30 | [self createTableView]; 31 | [self registerPreview]; 32 | 33 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(shortCut) name:@"ShortCut" object:nil]; 34 | [self shortCut]; 35 | } 36 | 37 | -(void)shortCut{ 38 | if ([_shortcutName length]>0) { 39 | [self.navigationController popToViewController:self animated:NO]; 40 | DetailViewController *detailVC =[[DetailViewController alloc]initWithTitle:self.shortcutName]; 41 | [self.navigationController pushViewController:detailVC animated:NO]; 42 | } 43 | } 44 | 45 | -(void)registerPreview{ 46 | if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { 47 | [self registerForPreviewingWithDelegate:self sourceView:self.tableViewList]; 48 | } 49 | else { 50 | NSLog(@"该设备不支持3D-Touch"); 51 | } 52 | } 53 | 54 | -(void)createTableView{ 55 | _tableViewList =[[UITableView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain]; 56 | _tableViewList.delegate =self; 57 | _tableViewList.dataSource =self; 58 | _tableViewList.tableFooterView =[[UIView alloc]init]; 59 | [self.view addSubview:_tableViewList]; 60 | [_tableViewList registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CellIdentifier"]; 61 | } 62 | 63 | -(void)initDefaultData{ 64 | self.title =@"复仇者联盟"; 65 | self.arrayData =@[@"钢铁侠",@"雷神",@"黑寡妇",@"美国队长"]; 66 | } 67 | 68 | #pragma mark - UIViewControllerPreviewingDelegate 69 | 70 | - (nullable UIViewController *)previewingContext:(id )previewingContext viewControllerForLocation:(CGPoint)location 71 | { 72 | NSIndexPath * indexPath =[_tableViewList indexPathForRowAtPoint:location]; 73 | 74 | UITableViewCell * cell = [_tableViewList cellForRowAtIndexPath:indexPath]; 75 | if (!cell) { 76 | return nil; 77 | } 78 | DetailViewController *detailVC =[[DetailViewController alloc]initWithTitle:[_arrayData objectAtIndex:indexPath.row]]; 79 | detailVC.preferredContentSize = CGSizeMake(0, 0); 80 | previewingContext.sourceRect = cell.frame; 81 | return detailVC; 82 | } 83 | 84 | - (void)previewingContext:(id )previewingContext commitViewController:(UIViewController *)viewControllerToCommit 85 | { 86 | [self.navigationController pushViewController:viewControllerToCommit animated:NO]; 87 | } 88 | 89 | #pragma mark -UITableViewDataSource 90 | 91 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 92 | return _arrayData.count; 93 | } 94 | 95 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 96 | UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:@"CellIdentifier" forIndexPath:indexPath]; 97 | cell.textLabel.text =[_arrayData objectAtIndex:indexPath.row]; 98 | cell.accessoryType =UITableViewCellAccessoryDisclosureIndicator; 99 | return cell; 100 | } 101 | 102 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 103 | DetailViewController *detailVC =[[DetailViewController alloc]initWithTitle:[_arrayData objectAtIndex:indexPath.row]]; 104 | [self.navigationController pushViewController:detailVC animated:YES]; 105 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 106 | 107 | } 108 | 109 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 110 | return 50; 111 | } 112 | 113 | - (void)didReceiveMemoryWarning { 114 | [super didReceiveMemoryWarning]; 115 | // Dispose of any resources that can be recreated. 116 | } 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /3DTouchSample/image/demo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/image/demo1.gif -------------------------------------------------------------------------------- /3DTouchSample/image/demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/image/demo2.gif -------------------------------------------------------------------------------- /3DTouchSample/image/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/image/preview.jpg -------------------------------------------------------------------------------- /3DTouchSample/image/shortcut.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RichardLeung/3DTouchSample/5679dd11f9b309c68603bf923643430172c9ad85/3DTouchSample/image/shortcut.jpg -------------------------------------------------------------------------------- /3DTouchSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // 3DTouchSample 4 | // 5 | // Created by RichardLeung on 15/10/31. 6 | // Copyright © 2015年 RL. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ###前言 4 | 半个月前拿到iPhone6S,第一时间体验了3D-Touch,感觉真的很赞,但是遗憾的是除了微信微博和苹果官方的App之外,其他App几乎没有对相关功能做3D-Touch的支持,于是第一时间在自家App做了相关的实践,经过一段时间的使用,效果还不错,昨晚写了这个Demo分享给大家,希望大家喜欢。 5 | ###实现 6 | 3D-Touch的功能分为两个部分:Shortcut和Preview。 7 | 8 | Shortcut和Preview效果如下图: 9 | 10 | 11 | 12 | 13 | 实际项目效果见下图 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------