web-dev-qa-db-ja.com

UIStoryBoardSegueを「キャンセル」する方法

誰もがセグエ遷移を条件付きで「停止」する方法を知っていますか?

テーブルビューのセルは、ドリルダウンの「詳細」ビューで表示できる製品を表しています。 (それはいくつかのことに依存します)

これで、私のアプリはすべての製品を「ロック解除」したと見なします。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
    ListaProdottiController *prodottiViewController = [segue destinationViewController];
    prodottiViewController.blocco = [self.fetchedResultsController objectAtIndexPath:selectedRowIndex];
}

この時点で行選択=>ドリルダウンをキャンセルするにはどうすればよいですか?

43
Fabio B.

IOS 6以降をターゲットにしている場合、これを行う最もクリーンな方法に関する私の知識は次のとおりです。

-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    if([identifier isEqualToString:@"show"])
    {
        NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
        Blocco *blocco = [self.fetchedResultsController objectAtIndexPath:selectedRowIndex];
        return [blocco meetRequiredConditions];
    }
    return YES;
}

方法があるところ

-(BOOL) meetsRequiredConditions;

Bloccoクラスで定義されたものは、ドリルダウンを許可する「モノのカップル」が有効な場合にYESを返します。

79
Joshcodes

それが正しい方法であるかどうかはわかりませんが、回避策を発見しました。

ストーリーボードから、View Controllerのステータスバーからセグエを関連付け(control +クリック)します。セグエにIDを付けます(例:switchSegue)。

今、あなたのコードのアクションから(私のコードではボタンを使用しています)、私は呼び出します:

 [self performSegueWithIdentifier:@"switchSegue" sender:sender];

そうすれば、セグエを実行するかどうかを制御できます。 here および here から私を助けたチュートリアルを試してください

お役に立てれば。

32
igbopie

私ははるかに簡単で整然としたアプローチを使用しています。

ストーリーボード

  1. 異なる識別子を持つ2つの同一のセルを作成します。例:「cellWithSegue」および「cellWithoutSegue」。
  2. 最初のセル( "cellWithSegue")を表示するセグエに接続します。
  3. セグエと2番目のセルを接続しないでください。

テーブルビュー

  1. CellForRowAtIndexPathで、セルをセグエにリンクするかどうかを決定するロジックを実装します。
  2. セグエにリンクする必要があるセルの場合は「cellWithSegue」識別子を使用し、残りの場合は「cellWithoutSegue」を使用します。

この方法は実装がはるかに簡単に見えるだけでなく、セグエの動作方法を変更することもありません。

18
zirinisp

私はここで間違っているかもしれませんが、これに苦労した後、シークをトリガーしたくないセルでのセルのユーザー操作を無効にしました(cellForRowAtIndexPath:で)。完全に動作しているようで、コードはたった1行です!

cell.userInteractionEnabled = NO;
14
SomaMan

最も簡単な解決策は、ストーリーボードに手動のセグエを作成し、以下に示すようにそれを使用することです。

[self performSegueWithIdentifier:@"loginSuccessSegue" sender:self];

または


@Fabio:私は同じ種類のユースケースのソリューションを得ようとしていましたが、ほとんど解決策を見つけました。

ユースケース1.セグエ遷移を条件付きで停止する2.宛先viewControllerを条件付きで変更する

解決:

「カスタム」セグエを使用します。以下の手順に従ってカスタムセグエを作成します1. UIStoryboardSegue "MyCustomSegue.h"のサブクラスを作成します

@interface MyCustomSegue : UIStoryboardSegue
@end

「MyCustomSegue.m」

ユースケース1および2を実装するためにinitWithIdentifierをオーバーライドします。nilを返すと、セグエがキャンセルされます/アクションは実行されませんViewControllerをインスタンス化し、それを宛先として設定します。宛先を古いxibファイルとして設定することもできます。このコードはコメント化されていますが、動作することを確認しました。

@implementation MyCustomSegue
- (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination{

    UIStoryboard *storyBoard= [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];

    UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:@"testIdentifier"];

    // MyViewController* viewController= [[MyViewController alloc]initWithNibName:@"MyViewController" bundle:nil];
    return [super initWithIdentifier:identifier source:source destination:viewController];
}
  1. 「実行」をオーバーライドする必要があります。

ここでもユースケース1を実装できます。

- (void)perform {
    // if either source or destination is nil, stop
    if (nil == self.sourceViewController || nil == self.destinationViewController) return;
    // return; //No Action. Segue will be cancelled
    UINavigationController *ctrl = [self.sourceViewController navigationController];
    [ctrl
     pushViewController:self.destinationViewController
     animated:YES];
}

お役に立てれば。明確でない場合は、Plzに書き込みます。

11
Johnson Mathew

これを行うための素敵で軽量な方法は、UITableViewDelegateメソッドtableView:willSelectRowAtIndexPath:内(該当する場合)です。 YMMV。

これが私がやっている方法です(iOS 5、ARC)。 View ControllerでBOOLインスタンス変数を使用します。最初はviewDidLoadでFalseに設定されています。 Interface Builderでテーブルセルがセグエに設定されている宛先View Controllerは、サーバーからロードされたデータの一部に依存しているため、データを取得するまでセグエが発生しないようにします。

簡略化すると、これは次のようになります。

@implementation SomeViewController {
    BOOL okayToSegue;
}

...

- (void)viewDidLoad
{
    [super viewDidLoad];
    okayToSegue = NO;
    // The success block for the data retrieval
    void(^successBlock)(void) = ^{
        // Other code...
        okayToSegue = YES;
    }
    [[ServerClient sharedClient] getDataFromServerSuccess:successBlock];
}

...

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!okayToSegue) {
        return nil;
    }
    return indexPath;
}

SharedClientのような詳細は無視します。成功ブロックを使用してAFHTTPClientサブクラスを呼び出す方法です。実際には、失敗ブロックなどもあります。

tableView:willSelectRowAtIndexPath:nilを返すと、テーブルセルをタップしても何も実行されません。 AFHTTPClientインスタンスからWordを(successBlockを介して)取得してから、View Controllerに必要なデータの準備ができて待機している場合にのみ、インスタンス変数を変更すると、将来のタップは正常に機能します。実際のコードでは、ユーザーに見える通知、またはセグメンテーションがまだ可能でないことを視覚的に明白に伝えることが必要です。

したがって、テーブルセルからのセグメンテーションが正常かどうかを判断するために必要なロジックは、多くの場合、この方法で実行できます。

4
JK Laiho

AppleのテンプレートがiPad popOverに対して行う方法は、手動セグエを使用することです。手動セグエは、pervertSegueWithIdentifierでトリガーする必要があるタッチをトリガーする自動セグエとは対照的です。

ビューのコントローラーアイコンからCtrlキーを押しながらドラッグすることを念頭に置いて、Ctrlキーを押しながらドラッグする代わりに手動のセグエを作成するには、セグエの識別子を設定し、IBで完了します。

manual segues

2
valexa

ここで私が見つけた別の解決策。

Mainstoryboard TableViewでは、セル(identifier = Cell)から宛先ビューに自動セグエを使用するときに、別の識別子(identifier = CellWithoutSegue)を使用して別のセルを追加することもできます。したがって、cellForRowAtIndexPathで新しいセルを作成するときは、必要なセル識別子を再利用するだけです(セグエの有無にかかわらず)。

それが役に立てば幸い!

(コードソースの例が必要な場合は教えてください)。

よろしく、

0
Dorine M