web-dev-qa-db-ja.com

performSegueWithIdentifierを使用せずにボタンをクリックしてもprepareForSegueが呼び出されない

スタンフォードiOSコースに基づいて、モーダルビューコントローラーで遊んでいます。デモでは、モーダルビューを起動するボタンがあり、クリックすると関数prepareForSegueが呼び出されます。コードと実装をプロジェクトに模倣しましたが、唯一の違いは、私のデモがiPhoneストーリーボードにあり、それらのデモがiPadにあることです。

モーダルビューコントローラーが起動している間、それより前にprepareForSegueを呼び出さないことに気付きました。私はスタンフォードプロジェクトを検索して、prepareForSegueが呼び出される前にセグエ動作を登録できる場所を確認しましたが、証拠はありません。誰でもこれにいくらか光を当てることができます。スタックオーバーフローを検索したところ、performSegueWithIdentifierの呼び出し実装がユーザーにないことがわかりました。しかし、スタンフォードのデモでは、彼らは決してそれをしません。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier hasPrefix:@"Create Label"]) {
        AskerViewController *asker = (AskerViewController *)segue.destinationViewController;
        asker.question = @"What do you want your label to say?";
        asker.answer = @"Label Text";
        asker.delegate = self;
    }

}

ストーリーボードの例を次に示します。 enter image description here

これが私のストーリーボードの例です: enter image description here

デバッガーでスタンフォードデモコードで停止すると、コールスタックはストーリーボードがセグエアクションを実行していることを示しますが、同じ結果を得るにはストーリーボードで何を設定する必要がありますか? enter image description here

26
Amro Younes

結局のところ、ボタンがモーダルビューを呼び出すビューコントローラーには、prepareForSegueが実装されている適切なクラスがありませんでした。これは、カスタムクラスではなくデフォルトのUIViewControllerでした。

私がそれを考え出したのは、viewDidLoadにブレークポイントを設定することでしたが、それでも壊れていなかったため、ストーリーボードでは、ボタンが実装されるビューに関連付けられた適切なクラスがなかったのではないかと疑っていました。

31
Amro Younes

この問題を持つ他の人のために、あなたがSwift 3を使用している場合、次の関数は正しい構文であるためエラーをスローしませんが、Swift 2関数:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // code
}

セグエで動作するには、Swift 3 "prepare"関数に更新する必要があります。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}
11
Manuel BM

テーブルビューの自動セグエを接続する場合、Amroの答え(対応するサブクラスを割り当てない)に加えて、prepareForSegueが呼び出されない別の2つのケースがあります。次のことを確認してください。

  1. テーブルビュープロトタイプセルからセグエを接続しました。notテーブルビューコントローラ。

  2. セグエ接続ポップアップメニューの「選択セグエ」グループの下にあるセグエを使用しました。not「アクセサリアクション」の下にあります。

Hooking up automatic segues

[画像をクリックして拡大]

10
DonVaughn

モーダルまたはプッシュセグエ以下のコードが常に呼び出されるかどうか

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"Create Label"]) {
        SignUpViewController *asker = segue.destinationViewController;
    }
}
5
bhavya kothari

私の場合、私のコントローラーが別のコントローラー(Eureka Form View Controller = FormViewController)を拡張していたため、それは次のようにperformSegue関数を実装しています。

open override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

私の機能は次のように実装されました。

func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

これを解決するために、先にオーバーライドを追加しました:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // code
}

出来上がり!

2
Vincent Guyard

同様の問題がありました。

思考プロセスは次のとおりです。

  1. 正しいメソッドシグネチャがあることを確認してください。 Swift 3。
  2. 次に、ボタン(またはセグエをトリガーするもの)をフックした方法が、ストーリーボードでセグエをフックした方法と一致することを確認します。ボタンを呼び出すこともありますが、そのボタンから目的のViewControllerにセグエを適切に接続していません。
  3. セグエの識別子が正しいことを確認してください。これはprepareForSegueが呼び出されない理由ではありませんが、これは特定のセグエが呼び出されない理由のみです。
1
Honey

セグエのソースとしてUICollectionViewCellでも同様の問題がありました。
ストーリーボードセグエが(performSegueWithIdentifierなしで)動作するためには、UICollectionViewCellのカスタムサブクラスを用意し、Classとして使用する必要があるようです。ストーリーボード上のCollectionViewCell用。

1
Mohit Joshi

私の場合、セグエを含むView Controllerのストーリーボードのクラス名でモジュールを設定しませんでした。 noneに設定され、モジュールフィールドをクリックすると、正しいプロジェクト/モジュールに設定され、問題が解決しました。

1
Logan Sease

私の場合、プロジェクトには複数のView Controllerの基本クラスがあります。その基本クラスには、すべての場合に呼び出されるわけではないprepareForSegue()の実装があります。問題は、基本クラスから継承し、そのprepareForSegue()実装をオーバーライドするView Controllerの1つで、super.prepareForSegue()を呼び出すのを忘れたことです。

0
ClayJ