2011-11-29 10 views
16

方法performSegueWithIdentifier:sender:を使用して、プログラムでstoryboard-fileから新しいViewControllerを開きます。これは魅力のように機能します。PerformSegueWithIdentifierで既存のViewControllerを使用することは可能ですか?

ただし、このメソッドが呼び出されるたびに、新しいViewControllerが作成されます。既存のViewControllerが存在する場合はそれを使用できますか?私はこの問題(apple-doc、Stack Overflow、...)について何も見つかりません。いくつかのフォーム要素を設定作成したViewControllerユーザーに とViewControllerが再び呼び出されることになるならば、フォーム要素は初期設定:(任意の助けをいただければ幸いです

があり

問題があります。

編集:。。。 私は多くの回答を感謝一方、私はプロジェクトに慣れていないんだし、あなたの答えをチェックすることはできません

+1

MVCパターンによると、共有オブジェクトまたはNSUserDefaultsにユーザー値を保存する必要があります。あなたの質問は完全に正しいわけではありません –

+0

あなたは正しいですが、この機能は実装されておらず、将来登場するでしょう!これは私の問題を解決するだろうが、ViewControllerをこのメソッドで再利用できるかどうか、問題は同じですか?私はこれが不可能ではないと思います。 – matzino

答えて

0

コントローラのプロパティを作成します

@property (nonatomic, weak) MyController controller; 

そして、この場合performSegueWithIdentifier:sender

if (self.controller == nil) 
{ 
self.controller = [MyController alloc] init] 
... 
} 

に遅延初期化のいくつかの種類を使用して、コントローラがすでに作成された場合、それが再利用されます。

+0

ありがとう、私はこれをチェックしたが、それは私のために働くdoesnt。私は実行メソッドからコンテキストでどのように怠惰な初期化が動作するのか知りませんか? – matzino

0

今日私はこの問題に直面しました。私がやったことは、手動でビューコントローラを作成してリファレンスを保存することです。 コントローラが必要になるたびに、最初に存在するかどうかを確認します。 このようなもの:

MyController *controller = [storedControllers valueForKey:@"controllerName"]; 

if (!controller) 
{ 
    controller = [[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:NULL] instantiateViewControllerWithIdentifier:@"MyControllerIdentifierOnTheStoryboard"]; 

    [storedControllers setValue:controller forKey:@"controllerName"]; 
} 

[self.navigationController pushViewController:controller animated:YES]; 

希望します。

+0

あなたのアドバイスをありがとう、このソリューションが動作するようだ。私は言及したd.lebedevのようなユーザー入力を保存することで私の問題を解決しました。あなたはnavigationControllerの助けを借りてviewcontrollerをプッシュしますが、代わりにperformSegueWithIdentifier-methodを使用できますか? – matzino

7

既存のUIViewControllerインスタンスをsegueで再利用するには、最初からsegueを作成し、独自の(既存の)宛先(UIViewController)を指定します。必要に応じてprepareForSegue:に電話することを忘れないでください。例えば

:次のコード

UIStoryboardSegue* aSegue = [[UIStoryboardSegue alloc] initWithIdentifier:@"yourSegueIdentifier" source:self destination:self.existingViewController] 
[self prepareForSegue:aSegue sender:self]; 
[aSegue perform]; 
+0

プレゼンテーションスタイルのようなこのアプローチでは、セグエの他のプロパティはどこから来ますか? – Benjohn

2

シングルトンビュー制御を行います。 それらをデスティネーションビューコントローラの実装に追加すると、segueは同じvcを再利用します。

static id s_singleton = nil; 
+ (id) alloc { 
    if(s_singleton != nil) 
     return s_singleton; 
    return [super alloc]; 
} 
- (id) initWithCoder:(NSCoder *)aDecoder { 
    if(s_singleton != nil) 
     return s_singleton; 
    self = [super initWithCoder:aDecoder]; 
    if(self) { 
     s_singleton = self; 
    } 
    return self; 
} 
+0

このアプローチで 'didReceiveMemoryWarning'をどうやって扱いますか? – expert

+0

s_singleton = nil; ? –

+0

あなたは私を救った!ありがとう:) – KiNG

-1

シングルトンクラスにViewControllerを作成する必要があります。

12

shouldPerforSegueWithIdentifierを使用して、segueの実行を許可するか、segueをキャンセルしてViewControllerを手動で追加します。 prepareForSegueにポインタを保持します。

...ヘッダ

@property (strong, nonatomic) MyViewController *myVC; 

...それは(UISplitViewControllerを使用しています)、標準の主従ユニバーサルアプリなら実装

-(BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{ 
    if([identifier isEqualToString:@"MySegueIdentifier"]){ 
     if(self.myVC){ 
      // push on the viewController 
      [self.navigationController pushViewController:self.myVC animated:YES]; 
      // cancel segue 
      return NO; 
     } 
    } 
    // allow the segue to perform 
    return YES; 
} 


-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if([segue.identifier isEqualToString:@"MySegueIdentifier"]){ 
     // this will only be called the first time the segue fires for this identifier 
     // retian a pointer to the view controller 
     self.myVC = segue.destinationViewController; 
    } 
} 
0

は、それが、これは以下のように、前回の詳細コントローラと新しいナビゲーションコントローラにviewControllersプロパティを設定することによって達成することができますすることができます。それ以外の場合は、ストーリーボード内のナビゲーションコントローラ内で再利用したいコントローラーを置くための追加ステップが必要になります。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([[segue identifier] isEqualToString:@"showDetail"]) { 
     NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
     NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath]; 
     UINavigationController* navigationController = (UINavigationController*)[segue destinationViewController]; 

     // retrieve previous detail controller. 
     DetailViewController* controller = self.detailViewController; 

     if(controller){ 
      // if we have an existing detail controller then set it on the navigation controller. 
      navigationController.viewControllers = @[controller]; 
     } 
     else{ 
      // this must be the first time, so store the detail view controller for next time, and we don't need to modify the navigation controller in this case. 
      controller = (DetailViewController *)[navigationController topViewController]; 
      self.detailViewController = controller; 
     } 

     // update the detail controller as normal. 
     [controller setDetailItem:object]; 
     controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; 
     controller.navigationItem.leftItemsSupplementBackButton = YES; 
    } 
} 

がストーリーボード毎回からアーカイブされていない詳細コントローラがあり、残念ながらそのビューにもロードされていることのオーバーヘッドがあります。しかし、すぐに割り当てが解除され、Applesのテンプレートではデフォルトの動作はディテール・コントローラがロードされていて破棄されているので、それが気にならない場合はおそらくそのようにするのが安全でしょう。

関連する問題