web-dev-qa-db-ja.com

performSeguewithIdentifierを呼び出すとshouldperformseguewithIdentifierが呼び出されません

View Controllerが2つあります。 view controller1には次のものがあります。

  • 私をviewcontroller2に連れて行くセグエ-このセグエは「showme」という名前で、viewcontrollerに接続されています
  • uIButtonのIBAction

私のコードでは、ボタンを押すアクションについて次のものがあります

@IBAction func buttonPress(sender: AnyObject) {
    println("button pressed")
        performSegueWithIdentifier("showme", sender: self)
}

また、次の方法があります:

override func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool {
    println("Should performing....")
    return true
}   

何らかの理由でshouldPerformSegueWithIdentifier関数が呼び出されることはありません。ただし、セグエをUIButtonで直接ViewController2に追加する場合はそうです。

ボタンアクション内で方向を呼び出すことは機能することを確認しました(以下を参照)が、これが機能する方法であると理解していることではありません。 prepareforSegueについても同様です。

@IBAction func buttonPress(sender: AnyObject) {
    println("button pressed")
    if (shouldPerformSegueWithIdentifier("showme", sender: self)){
        performSegueWithIdentifier("showme", sender: self)}
} 
43
es3dev

次の理由により、この動作は完全に自然です。

1)shouldPerformSegueWithIdentifierは、Storyboardsで設定されたセグエがトリガーされるようにするために使用されるため、Storyboard Seguesの場合にのみ呼び出され、not実際にセグエを実行します。

2)performSegueWithIdentifierを自分で呼び出すとき、shouldPerformSegueWithIdentifiernotと呼ばれます。やっている。 performSegueWithIdentifierを呼び出しても意味はありませんが、NOからshouldPerformSegueWithIdentifierを返します。

76
nburk

@nburkの答えは絶対に正しいです。

ただし、shouldPerformSegueWithIdentifier:sender:への呼び出しがコード内で行われた場合でも、performSegueWithIdentifier:sender:が呼び出されると、状況によっては役立つ場合があることを理解しています。

たとえば、セグエを実行するかどうかを決定するためにいくつかの検証を行い、このロジックを単一の場所に保持し、次のような場所の条件全体に複製しないようにします。

if (self.shouldPerformSegue) {
     [self performSegueWithIdentifier:identifier sender:sender];
}

これは、次のようにperformSegueWithIdentifier:sender:をオーバーライドすることで簡単に実現できます。

- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    if ([self shouldPerformSegueWithIdentifier:identifier sender:sender]) {
        [super performSegueWithIdentifier:identifier sender:sender];
    }
    // otherwise do nothing
}

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    return self.shouldPerformSegue;
}

このようにして、shouldPerformSegueWithIdentifier:sender:を使用して、IBとコードトリガーセグエの両方を許可/拒否するロジックを定義できます。

29
tanzolone

上記の答えとして。 performSegueWithIdentifierを呼び出すと、shouldPerformSegueWithIdentifierは呼び出されません。

例として:

スワイプできる画像を表示するために、コンテナビュー内にセグエが埋め込まれているとします。また、VCが読み込まれたときに埋め込みセグエがすぐに起動します。ただし、リモートAPIから画像をダウンロードする必要がある場合、埋め込みに表示する画像がないため、アプリがクラッシュしますセグエ/コンテナビュー。

この場合、shouldPerformSegueWithIdentifierが必要になります。

Falseがfalseを返し、セグエが発生しない場合は、shouldPerformSegueWithIdentifierでチェックインするブール値を設定できます。そして、アプリが画像をダウンロードしたら、performSegueWithIdentifierを呼び出すことができます

3
user2722667

完璧なソリューションをありがとう@tanzolone。 Swift 5のコードを書き直しました。

shouldPerformSegueの前にperformingSegueを強制的に呼び出すには、クラスでperformingSegueをオーバーライドできます。

override func performSegue(withIdentifier identifier: String, sender: Any?) {
    if shouldPerformSegue(withIdentifier: identifier, sender: sender) {
        super.performSegue(withIdentifier: identifier, sender: sender)
    }
}

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    // Your code (return true if you want to perform the segue)
}
0
Vergiliy

このコードを使用している場合は、削除する必要があります。

[self performSegueWithIdentifier:name sender:sender];

0
alicanozkara