web-dev-qa-db-ja.com

UITableViewCellのタップで実行される条件付きセグエ

Xcode 4.2を使用してiOS 5のプロジェクトに取り組んでいます。 UITableViewControllerが1つあり、ユーザーがテーブルセルをタップするとセグエを実行したいのですが、目的のView Controllerはそのセルで実行されるアクションに依存します。たとえば、ユーザーがセルをタップするとSomeViewControllerをロードしたいが、ユーザーが編集モードで同じセルをタップした場合はAnotherViewControllerをロードしたい。残念ながら、Xcode 4.2ストーリーボードビルダーの同じセルに複数のセグエを設定する方法はありません。そうしないとわかりません。おそらく、コードエディターで手動でセグエを作成する方法があります。一般的に私が達成したいのは、あるView Controllerを使用してセルで表されるアイテムを「入力」し、別のView Controllerを使用して同じセルで表されるアイテムを「編集」する方法をユーザーに提供することです。ただし、table-edit-modeのときに2番目のView Controller(エディター)に切り替えることは私の最初でしたが、もっと良い方法があるかもしれません。任意の助けをいただければ幸いです。

39
Darrarski

ストーリーボードを見ながら、ソースView ControllerからDestination View Controllerにコントロールドラッグします。これにより、ソースView Controllerからプログラムで直接トリガーできるセグエが作成されます。セグエに名前を付けてください。この名前は、ソースView ControllerのperformSegue:withIdentifier:メソッドに渡すものです。

54

これ以外の多くの場所で上記の選択されたものを読んだ後、余分な答えを追加しています-それはis正しい答えです-私は自分が普通にトリガーするタッチを検出する方法を疑問に思っていますセグエ。テーブルビューのセルから次のコントローラーにCtrlキーを押しながらドラッグして通常の方法でセグエを作成すると、2つのことが自動的に行われます。

  1. セル内のタッチが検出された
  2. セグエが実行されます

もちろん、セグエをブロックすることはできません。

条件付きセグエにしたい場合、(他の回答で述べたように)そのセグエを削除し、UITableViewControllerから新しいセグエを作成します(ストーリーボードではなくオブジェクトナビゲータからドラッグします)。次のコントローラー-名前を付けます。

その後-そして、これは私が行方不明だった部分です-tableView:didSelectRowAtIndexPath以下のように、プログラムおよび条件付きでセグエを実行するためのTable View Controller。

セルを特定する必要があることに注意してください。そうすれば、興味のあるセルが選択されたかどうかを知ることができます。あなたは静的テーブルのインデックスパスを知ることでそれを行うことができますが、私はIBにセルの一意の識別子を設定することを好みます(静的テーブルなので、デキューに必要ではありませんが)。静的テーブルでセルを上下に移動する場合、このコードを変更する必要はありません。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Find the selected cell in the usual way
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

    // Check if this is the cell I want to segue from by using the reuseIdenifier
    // which I set in the "Identifier" field in Interface Builder
    if ([cell.reuseIdentifier isEqualToString:@"CellIWantToSegueFrom"]) {

    // Do my conditional logic - this was the whole point of changing the segue
    if (myConditionForSegueIsSatisfied) {
        // Perform the segue using the identifier I was careful to give it in IB
        // Note I'm sending the cell as the sender because that's what the normal
        // segue does and I already had code counting on that
        [self performSegueWithIdentifier:@"SegueIdentifer" sender:cell];
    }
}

セグエでセルを送信する方法に注意してください-セルからの通常のセグエがそれを行い、元々nilを渡しており、それに依存していたコードが機能しなくなりました。

33
Rhubarb

これは古い質問であり、いくつかの素晴らしい正解ですが、これに遭遇したときに役立つと感じた追加情報を投稿します:

  1. SomeVCからAnotherVCにctl + dragでストーリーボードにセグエを作成する場合は、それを削除します。

  2. オブジェクトナビゲータで、ViewControllerレベルで(通常はVCの名前の下の階層で最初に)SomeVCからAnotherVCにctl +ドラッグします。セグエに一意の識別子を付けます。

  3. 上記のようにtableView: didSelectRowAtIndexPath:を実装します。

  4. tableView: didSelectRowAtIndexPath:switchステートメントを使用すると役立つことがわかりました

    switch (indexPath.row) {
    case 0:
        [self performSegueWithIdentifier:@"yourIDHere" sender:self];
        break;
    case 1:
        // enter conditional code here...
        break;
    case 2:
        // enter conditional code here...
        break;
    // ... for however many cells you require
    
    default:
        break;
    

    }

みなさん、すばらしい回答をありがとう。

5
Chris Holloway

以下を実装することにより、カスタムUIViewControllerでセグエのオープンを簡単に制御できます。

override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool { return true // or false, depending on what you need }

0
vedrano