UITableViewのdidSelectRowAtIndexPathまたはprepareForSegueメソッドを使用しますか?


101

ストーリーボードを使用していて、UITableViewを持っています。テーブルから詳細なVCにプッシュするセグエ設定があります。しかし、これを処理するにはどの方法を使用すればよいですか?いくつかのオブジェクトを詳細ビューに渡す必要があります。しかし、私は使用しますdidSelectRowAtIndex-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

回答:


199

使用prepareForSegue:sender:する場合、後でテーブルビューの外部のコントロールからセグエをトリガーすることを決定しても、それほど変更する必要はありません。

prepareForSegue:sender:私はこのような何かをお勧めしたいので、メッセージは、現在のビューコントローラに送信されます。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Assume self.view is the table view
    NSIndexPath *path = [self.tableView indexPathForSelectedRow];
    DetailObject *detail = [self detailForIndexPath:path];
    [segue.destinationViewController setDetail:detail];
}

Swiftの場合:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let path = self.tableView.indexPathForSelectedRow()!
    segue.destinationViewController.detail = self.detailForIndexPath(path)
}

1
では、indexPathに基づいてオブジェクトを渡して実装する方法の例を挙げてください。
ジョン

4
ここにself.viewいるだけではいけませんsenderか?私は[self.view indexPathForSelectedRow]仕事に行くことさえできなかった、私はしなければならなかった[sender indexPathForSelectedRow];
ladookie

Swiftでこれをどのように行いますか?
ユーザー、

@robmayoff Swift用にこれを更新してくれてありがとう。最近の言語変更を反映するために、少し編集を加えました。これが他の人に役立つことを願っています
ザックシャピロ

が呼び出されたtableView.indexPathForSelectedRow()ときに正しい値が含まれるのは奇妙です。prepareFroSegue...tableView(_:didSelectrowAtIndexPath:)
Nicolas Miari、2016年

5

私はこれをしました、そしてそれはうまくいきました

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"Row Selected = %i",indexPath.row);

    [self performSegueWithIdentifier:@"testID" sender:self.view];    
}

11
それは意味がありません。セグエまたはテーブルビューデリゲートを使用する必要があります。Cellからセグエを作成するだけで、コードを書かなくても自動的に同じことを実行できます。
Yariv Nissim 2013年

3
didSelectRowなしでセルにセグエを割り当てるにはどうすればよいですか?
Morkrom 2013年

3

送信者がUITableViewCellの場合、セルのindexPathをクエリするようUITableViewに要求できます。

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let cell = sender as? UITableViewCell {
            let indexPath = self.tableView.indexPathForCell(cell)!
            assert(segue.destinationViewController.isKindOfClass(DetailViewController))
            let detailViewController = segue.destinationViewController as! DetailViewController
            detailViewController.item = self.items[indexPath.row] // like this
        }
    }

1

tableViewプロパティが別のクラスにあり、セクションが1つしかない場合は、次のようにtagプロパティを使用してセルの行を格納できます。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

     cell.tag = indexPath.row;

     return cell;
}

そしてsender、タグに行の値が含まれているのと同じセルであるため、アクセスできます。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    MyDestinationViewController *destinationViewController = segue.destinationViewController;
    destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
}

1

self.tableView.indexPathForSelectedRow選択したセルを返しますが、送信側セルをセグエしません。たとえば、送信側セルが選択されていない(アクセサリアクション)、または複数選択の場合です。最良の方法は、セグエ送信者のindexPathを取得することです。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    __auto_type itemViewController = (id<ItemViewController>)segue.destinationViewController;
    itemViewController.senderIndexPath = [self.tableView indexPathForCell:sender];
}

Swiftの場合:

protocol ItemViewController {
    var senderIndexPath : IndexPath? { get set }
    var selectedIndexPaths : [IndexPath]? { get set }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if  let cell = sender as? UITableViewCell,
        var itemViewController = segue.destination as? ItemViewController {
        itemViewController.senderIndexPath = tableView.indexPath(for: cell)
        itemViewController.selectedIndexPaths = tableView.indexPathsForSelectedRows
    }
}

0

使用prepareForSegue:する場合は、送信者が誰であるかを確認し、別のコードを実行できます

例えば迅速に

override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)
{
   var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)

   if senderIsTableviewCell
   {
       //do something
   }
}

2
ただ行う:tableViewCell = sender asとすると?UITableViewCell {//何かをする}。送信者をUITableViewCellにキャストできない場合、「何かを実行」は実行されません。
mbeaty 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.