3D从UITableViewCell触摸Peek和Pop如何将数据交给其他UIViewController?

我的应用程序在Core Data对象中存储不同的属性。 它们都显示在一个UITableView中,如果你点击一个单元格,就会显示一个DetailView。 像Master-Detail-XCode-Template一样。

现在我想用peek和pop来实现3D Touch。 就像在邮件应用程序中,3D触摸一个单元格,获得预览,按下更深,popup细节。

到目前为止,我已经得到了这个工作,但我无法弄清楚如何传递相应的数据

- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location 

 - (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit 

到另一个DetailViewController。

如果你只是点击单元格(没有3D触摸),我交出数据

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath]; [[segue destinationViewController] setDetailItem:object]; 

我正在使用一个

 id detailItem 

在每个ViewController中,我将相应的对象设置为它。

所以我尝试了类似的工作,所以在我的DetailViewController我的“detailItem”需要从选定的(3D触摸)单元格相应的核心数据对象。

感谢帮助 !

使用故事板ID从故事板中获取目标视图控制器,并传递您在prepareForSegue方法中执行的对象。

以下是我用来传递数据的代码。 它在Swift中,在Objective C中应该是相似的。让我知道如果你想要Objective C的版本。

 func previewingContext(previewingContext: UIViewControllerPreviewing,viewControllerForLocation location: CGPoint) -> UIViewController? method: // Obtain the index path and the cell that was pressed. guard let indexPath = tableView.indexPathForRowAtPoint(location), cell = tableView.cellForRowAtIndexPath(indexPath) else { return nil } // Create a destination view controller and set its properties. guard let destinationViewController = storyboard?.instantiateViewControllerWithIdentifier("DestinationViewController") as? DestinationViewController else { return nil } let object = fetchedResultController.objectAtIndexPath(indexPath) destinationViewController.detailItem = object /* Set the height of the preview by setting the preferred content size of the destination view controller. Height: 0.0 to get default height */ destinationViewController.preferredContentSize = CGSize(width: 0.0, height: 0.0) previewingContext.sourceRect = cell.frame return destinationViewController } 

如果您正在使用从单元格到新视图控制器的storyboard segues,则发件人是表视图单元格。

所以你可以实现prepareForSegue:如此:

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([sender isKindOfClass:[UITableViewCell class]]) { UITableViewCell *cell = sender; NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; id viewController = segue.destinationViewController; // Get your data object // Pass it to the new view controller } } 

根据Dheeraj的回复,调整一些代码来纠正tableview单元格的错误触摸位置。 假设我们需要将名为type的值传递给目标控制器。

 - (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{ // check if we're not already displaying a preview controller if ([self.presentedViewController isKindOfClass:[DetailViewController class]]) { return nil; } CGPoint cellPostion = [self.tableview convertPoint:location fromView:self.view]; NSIndexPath *path = [self.tableview indexPathForRowAtPoint:cellPostion]; if (path) { UITableViewCell *cell = [self.tableview cellForRowAtIndexPath:path]; type = [[self.data objectAtIndex:path.row] integerValue]; // shallow press: return the preview controller here (peek) UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; DetailViewController *previewController = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"]; previewController.type = type; previewingContext.sourceRect = [self.view convertRect:cell.frame fromView:self.tableview]; return previewController; } return nil; 

}