30

ユーザーが動的TableViewのセルに触れたときにポップオーバーセグエを実行する必要があります。しかし、このコードでこれを実行しようとすると:

- (void)tableView:(UITableView *)tableview didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
        [self performSegueWithIdentifier:@"toThePopover" sender:[tableView cellForRowAtIndexPath]];
    //...
} 

エラーが発生するよりも:

不正な構成

アンカーのないポップオーバー セグエ

これを行う方法はありますか (動的 TableView から手動でポップオーバー セグエを実行するため)?

4

4 に答える 4

61

私は今夜​​、これと同じ問題に直面しました。いくつかの回避策があります(ポップオーバーを昔ながらの方法で提示することを含む)。

この例では、カスタムセルクラスに格納されているオブジェクトがあります。セルが選択されたら、このような関数を呼び出して、オブジェクトに関するpopOverViewControllerの詳細を開き、テーブル内の対応するセルをポイント(アンカー)します。

    - (void)openCustomPopOverForIndexPath:(NSIndexPath *)indexPath{
        CustomViewController* customView = [[self storyboard] instantiateViewControllerWithIdentifier:@"CustomViewController"];

        self.myPopOver = [[UIPopoverController alloc]
                                   initWithContentViewController:customView];
        self.myPopOver.delegate = self;
        //Get the cell from your table that presents the popover
        MyCell *myCell = (MyCell*)[self.tableView cellForRowAtIndexPath:indexPath];
        CGRect displayFrom = CGRectMake(myCell.frame.origin.x + myCell.frame.size.width, myCell.center.y + self.tableView.frame.origin.y - self.tableView.contentOffset.y, 1, 1);
        [self.myPopOver presentPopoverFromRect:displayFrom
                                             inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
    }

この方法の問題は、カスタム初期化子を持つためにポップオーバービューが必要になることが多いことです。これは、ビューをxibではなくストーリーボードで設計し、セルに関連付けられたオブジェクトをその表示に使用するパラメーターとして受け取るカスタムinitメソッドを使用する場合に問題になります。また、動的なアンカーポイントが必要なため(一見したところ)、ポップオーバーセグエを使用することはできません(セルのプロトタイプにアンカーすることはできません)。これが私がしたことです:

  1. まず、ViewControllerビューに非表示の1pxX1pxUIButtonを作成します。(ビュー内の任意の場所に移動できるようにするボタンの制約を与えることが重要です)
  2. 次に、View Controllerにボタン(私は私のpopOverAnchorButtonと呼びます)のアウトレットを作成し、セグエを非表示のボタンからセグエしたいViewControllerにドラッグします。それをpopOverセグエにします。

これで、「合法的な」アンカーを備えたポップオーバーセグエができました。ボタンは非表示になっているため、誤ってボタンに触れることはありません。これはアンカーポイントにのみ使用しています。

このように、関数で手動でセグエを呼び出します。

    - (void)openCustomPopOverForIndexPath:(NSIndexPath *)indexPath{
        //Get the cell from your table that presents the popover
        MyCell *myCell = (MyCell*)[self.tableView cellForRowAtIndexPath:indexPath];

        //Make the rect you want the popover to point at.
        CGRect displayFrom = CGRectMake(myCell.frame.origin.x + myCell.frame.size.width, myCell.center.y + self.tableView.frame.origin.y - self.tableView.contentOffset.y, 1, 1);

        //Now move your anchor button to this location (again, make sure you made your constraints allow this)
        self.popOverAnchorButton.frame = displayFrom;
        [self performSegueWithIdentifier:@"CustomPopoverSegue" sender:myCell];
    }

そして……出来上がり。今、あなたはセグエの魔法をすべての素晴らしさで使用していて、あなたはあなたの細胞を指しているように見える動的なアンカーポイントを持っています。これで-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender、送信者をセルのクラスにキャストし(送信者のタイプと呼び出されているセグエを適切にチェックする場合)、セグエのdestinationViewControllerにセルのオブジェクトを指定できます。

これが役立つかどうか、または誰かがフィードバックや改善を持っているかどうかを教えてください。

于 2013-01-25T03:24:24.343 に答える
3

セグエではなくコードを使用しますが、タッチされたセルからポップオーバーを表示する別の方法としてこの回答を追加するだけです。それは非常に単純ですが、iOS 4 から iOS 7 まで私にとってはうまくいきました:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    //get the data of the row they clicked from the array
    Url* clickedRec = [self.resultsArray objectAtIndex:indexPath.row];

    //hide the popover in case it was already opened from a previous touch.    
    if (self.addNewPopover.popoverVisible) {
            [self.addNewPopover dismissPopoverAnimated:YES];
            return;
        }

    //instantiate a view controller from the storyboard
    AddUrlViewController *viewControllerForPopover =
    [self.storyboard instantiateViewControllerWithIdentifier:@"addUrlPopup"];

    //set myself as the delegate so I can respond to the cancel and save touches.
    viewControllerForPopover.delegate=self;
    //Tell the view controller that this is a record edit, not an add        
    viewControllerForPopover.addOrEdit = @"Edit";
    //Pass the record data to the view controller so it can fill in the controls            
    viewControllerForPopover.existingUrlRecord = clickedRec;

    UIPopoverController *popController = [[UIPopoverController alloc]
                                          initWithContentViewController:viewControllerForPopover];

    //keep a reference to the popover since I'm its delegate        
    self.addNewPopover = popController;

    //Get the cell that was clicked in the table. The popover's arrow will point to this cell since it was the one that was touched.
    UITableViewCell *clickedCell = [self.tableView cellForRowAtIndexPath:indexPath];

    //present the popover from this cell's frame.
    [self.addNewPopover presentPopoverFromRect:clickedCell.frame inView:self.myTableView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
于 2014-06-30T14:58:57.543 に答える