私のアプリは、CoreDataオブジェクトにさまざまな属性を格納しています。それらはすべてUITableViewに表示され、セルをクリックするとDetailViewが表示されます。 Master-Detail-XCode-Templateのような通常のもの。
今度は、ピークアンドポップで3DTouchを実装したいと思います。メールアプリと同様に、セルを3Dタッチし、プレビューを表示し、さらに深く押して、詳細をポップします。
私はこれまでこれを機能させましたが、対応するデータを渡す方法がわかりません
- (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で、対応するオブジェクトをそれに設定します。
だから私は仕事に似たものを手に入れようとしているので、私の「detailItem」は選択された(3Dタッチされた)セルからの対応するコアデータオブジェクトを必要とします。
手伝ってくれてありがとう !
ストーリーボードIDを使用してストーリーボードから宛先Viewコントローラーを取得し、prepareForSegueメソッドで実行しているオブジェクトを渡します。
以下は、データを渡すために使用するコードです。 Swiftでは、ObjectiveCでも同様のはずです。ObjectiveCバージョンが必要な場合はお知らせください。
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
}
セルから新しいビューコントローラへのストーリーボードセグエを使用している場合、送信者はテーブルビューセルです。
したがって、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の応答に基づいて、テーブルビューセルの間違ったタッチ位置を修正するためにいくつかのコードを調整します。 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;
}