③ Peek 和 Pop
要实现Peek和Pop的操作如下
第一步:让某个ViewController遵循 UIViewControllerPreviewingDelegate协议
第二步:在该ViewController合适的地方注册3DTouch,使得该viewController可以参与peek和pop
[self registerForPreviewingWithDelegate:self sourceView:self.view];
其中的sourceView,顾名思义,资源视图。在用户给与压力时会被周围模糊的视图包围,如果继续就会触发peek和pop操作。假如需要支持3DTouch的ViewController是 TableViewController那么最好将source设置为tableView;对于CollectionViewController也是相同的道理。(在研究的过程中,我发现如果在CollectionViewController注册时将sourceView注册为self.view会出现位置偏移等奇怪的现象。)苹果在官方文档中,说到一个viewController可以注册多个sourceView,但是一个sourceView不能够在一个单一的viewController中被多次注册,我尝试注册多次,控制台打印了如下信息:
Warning: Attempt to present <DetailViewController: 0x158929090> on <TableViewController: 0x1575c8510> which is already presenting (null)
第三步:实现委托方法。
//Peek方法 以TableViewController为例
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
//得到indexPath和cell
NSIndexPath *indexpath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexpath];
//创建要返回的viewController
DetailViewController *detailVC = [[DetailViewController alloc] init];
detailVC.labelText = [NSString stringWithFormat:@"%ld",indexpath.row+1];
NSInteger i = indexpath.row +1;
//设置预览视图的高度
detailVC.preferredContentSize = CGSizeMake(0.0, i > 10 ?15*i:150);
//设置清晰显示的范围
previewingContext.sourceRect = cell.frame;
return detailVC;
}
peek的快捷操作
在DetailViewController的.m文件中实现
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems;
方法为peek添加previewAction,有两种类型的previewAction,一个是单独的,一个是分组的,具体代码如下:
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
//创建单个的action
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"UIPreviewActionStyleDefault" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"UIPreviewActionStyleDefault");
}];
UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"UIPreviewActionStyleSelected" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"UIPreviewActionStyleSelected");
}];
UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"UIPreviewActionStyleDestructive" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"UIPreviewActionStyleDestructive");
}];
//创建两个action
UIPreviewAction *action4 = [UIPreviewAction actionWithTitle:@"UIPreviewActionStyleDefault" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"UIPreviewActionStyleDefault");
}];
UIPreviewAction *action5 = [UIPreviewAction actionWithTitle:@"UIPreviewActionStyleDefault" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"UIPreviewActionStyleDefault");
}];
//将这两个action加入到组中
UIPreviewActionGroup *group = [UIPreviewActionGroup actionGroupWithTitle:@"group" style:UIPreviewActionStyleDefault actions:@[action4,action5]];
//返回
return @[action1,action2,action3,group];
}
Pop的实现
//Pop方法
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
[self showViewController:viewControllerToCommit sender:self];
}
在Commit的方法中,一般是采取[self showViewController:viewControllerToCommit sender:self]方法来显示这个viewController,通常来说preview和commit的viewController是同一个。
总结:在3DTouch刚刚出来时我非常期待它的功能,因为这是另一种层面的交互,我希望能够体验。经过苹果的更新和各个开发者的适配,很多的软件都支持了3DTouch。在这么久的使用过程中,总结下我觉得最为实用的功能:按压屏幕左边缘切到后台(相当于点击两次home键)、按压键盘快速调节光标、主屏幕的一些shortcutItem(如支付宝的付款、扫一扫、贴吧的一键签到、短信的新信息),这些利用3DTouch实现的功能,对比传统操作,都是具有明显优势的。但是,对于peek和pop就目前的操作方式和使用习惯来看是有些鸡肋的。不能否认这是一个有潜力的创造,开发者可以结合新的压力相关的属性来开发类似于苹果自家备忘录一样的应用,这一定也会更具有想象力。
(相关demo在整理好之后会上传)