首先 有几个要知道的手势
第一, 在点击app icon 的手长按 并且用力一点(用点力不然没效果,不会弄坏手机,坏了也不是我的,哈哈!) 就会出现 几个Item。
第二,(1)在app 里面 长按 也要用力往下压 跟着就会可以弹出 自定义的 ViewController。这个时候如果你放手了那么就会消失。
(2)如果 长按 往下压 弹出了自定义的ViewController 之后跟着网上移动,就可以出现 选择Action。
第三,如果 长按 往下压 弹出了自定义的ViewController,然后更加 用力一点 比 弹出的ViewController的力度 更加大一点 那么 自定义的这个ViewController 就会 相当于push 进来了。
首先来一个获取版本号,因为3D Touch 只有在iOS9 才会有,在后面演示的代码就不上这个判断。
#define IOS_VERSION [[[UIDevice currentDevice] systemVersion] floatValue]
1、首先在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 去创建 item ,这几个item 就是在点击icon 的时候出现的.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
BOOL result = YES;
//系统版本适配
if (IOS_VERSION < 9.0) return result;
NSArray *items = [UIApplication sharedApplication].shortcutItems;
if (items.count == 0) {
//也可以在info.plist 中创建
[self createShortIcon];
}
//判断是否是从shortitem 启动的程序
if (launchOptions[@"UIApplicationLaunchOptionsShortcutItemKey"]) {
_currentShortItem = launchOptions[@"UIApplicationLaunchOptionsShortcutItemKey"];
//这里返回值很重要、返回no,不会再调用performActionForShortcutItem这个回调方法
// result = NO;
}
return result;
}
- (void)createShortIcon {
UIApplicationShortcutIcon *shortIcon1 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeHome];
UIApplicationShortcutItem *shortItem1 = [[UIApplicationShortcutItem alloc] initWithType:[NSString stringWithFormat:@"%@.First",BundleId] localizedTitle:@"FistItem" localizedSubtitle:@"subtitle" icon:shortIcon1 userInfo:nil];
UIApplicationShortcutIcon *shortIcon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"home@2x.png"];
UIApplicationShortcutItem *shortItem2 = [[UIApplicationShortcutItem alloc] initWithType:[NSString stringWithFormat:@"%@.Second",BundleId] localizedTitle:@"SecondItem" localizedSubtitle:nil icon:shortIcon2 userInfo:nil];
[[UIApplication sharedApplication] setShortcutItems:@[shortItem1,shortItem2]];
}
/**
处理shortcotItem
*/
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
[self handleItem:shortcutItem];
}
- (void)handleItem:(UIApplicationShortcutItem *)shortItem {
//处理shortitem事件
if ([shortItem.type isEqualToString:[NSString stringWithFormat:@"%@.First",BundleId]]) {
NSLog(@"First Item-----%@>>>>>>%@",[NSBundle mainBundle],[NSBundle mainBundle].bundleIdentifier);
}else if ([shortItem.type isEqualToString:[NSString stringWithFormat:@"%@.Second",BundleId]]) {
NSLog(@"Second Item-----%@>>>>>>%@",[NSBundle mainBundle],[NSBundle mainBundle].bundleIdentifier);
}
[self showAlert];
}
- (void)showAlert {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"aaa" message:[NSString stringWithFormat:@"%d",22] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil];
[alertView show];
}
//在每次激活程序时先置空一些设置
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 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.
if (!_currentShortItem) return;
[self handleItem:_currentShortItem];
_currentShortItem = nil;
}
2、接着这里要说的是 在 长按touch ViewController 中tableView 对应Cell 添加Touch 事件
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdenfitier = @"CellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdenfitier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdenfitier];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.text = _cellArr[indexPath.row];
if (IOS_VERSION >= 9.0 && (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)) {
[self registerForPreviewingWithDelegate:self sourceView:cell];
}
return cell;
}
在viewController 中实现 Touch 协议方法
#pragma mark - UIViewControllerPreviewingDelegate
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
//重按时显示的预览界面
return self.vc;
}
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
//继续用力按执行执行这个方法, 这里事件预览界面展示出来
[self showViewController:self.vc sender:self];
}
//重按显示预览界面时,向上滑动出现的菜单选择、一定要在
//-(UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
//回调返回的UIViewController中实现这个方法,不然无法显示菜单选项
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"you" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
UIViewController *vc = [UIViewController new];
[vc.view setBackgroundColor:[UIColor greenColor]];
[[self topViewController] presentViewController:vc animated:YES completion:nil];
}];
UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"and" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
UIViewController *vc = [UIViewController new];
[vc.view setBackgroundColor:[UIColor greenColor]];
[[self topViewController].navigationController pushViewController:vc animated:YES];
}];
UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"I" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
}];
return @[action1, action2, action3];
}
- (UIViewController *)topViewController {
return [self topviewControllerViewRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController];
}
- (UIViewController *)topviewControllerViewRootViewController:(UIViewController *)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabbarController = (UITabBarController *)rootViewController;
return [self topviewControllerViewRootViewController:tabbarController.selectedViewController];
}else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController;
return [self topviewControllerViewRootViewController:navigationController.visibleViewController];
/**
* topViewController代表当前navigation栈中最上层的VC,而visibleViewController代表当前可见的VC,它可能是topViewController,也可能是当前topViewController present出来的VC。因此UINavigationController的这两个属性通常情况下是一样,但也有可能不同。
*/
}else if (rootViewController.presentedViewController){
UIViewController *presentViewController = rootViewController.presentedViewController;
return [self topviewControllerViewRootViewController:presentViewController];
/**
* presentedViewController:The view controller that is presented by this view controlller(read-only),被本视图控制器present出来的的视图控制器(只读)
presentingViewController:The view controller that presented this view controller. (read-only),present出来本视图控制器的视图控制器(只读)
parentViewController:The parent view controller of the recipient(容器). (read-only)
*/
}else {
return rootViewController;
}
}
3、在自定义的vc弹出时 然后我们往上移动那么就会出现Action
//重按显示预览界面时,向上滑动出现的菜单选择、一定要在
//-(UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
//回调返回的UIViewController中实现这个方法,不然无法显示菜单选项
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"you" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
UIViewController *vc = [UIViewController new];
[vc.view setBackgroundColor:[UIColor greenColor]];
[[self topViewController] presentViewController:vc animated:YES completion:nil];
}];
UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"and" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
UIViewController *vc = [UIViewController new];
[vc.view setBackgroundColor:[UIColor greenColor]];
[[self topViewController].navigationController pushViewController:vc animated:YES];
}];
UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"I" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
}];
return @[action1, action2, action3];
}
- (UIViewController *)topViewController {
return [self topviewControllerViewRootViewController:[UIApplication sharedApplication].delegate.window.rootViewController];
}
- (UIViewController *)topviewControllerViewRootViewController:(UIViewController *)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabbarController = (UITabBarController *)rootViewController;
return [self topviewControllerViewRootViewController:tabbarController.selectedViewController];
}else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController;
return [self topviewControllerViewRootViewController:navigationController.visibleViewController];
/**
* topViewController代表当前navigation栈中最上层的VC,而visibleViewController代表当前可见的VC,它可能是topViewController,也可能是当前topViewController present出来的VC。因此UINavigationController的这两个属性通常情况下是一样,但也有可能不同。
*/
}else if (rootViewController.presentedViewController){
UIViewController *presentViewController = rootViewController.presentedViewController;
return [self topviewControllerViewRootViewController:presentViewController];
/**
* presentedViewController:The view controller that is presented by this view controlller(read-only),被本视图控制器present出来的的视图控制器(只读)
presentingViewController:The view controller that presented this view controller. (read-only),present出来本视图控制器的视图控制器(只读)
parentViewController:The parent view controller of the recipient(容器). (read-only)
*/
}else {
return rootViewController;
}
}