2013-04-17 14 views
21

私はストーリーボードコンテナビューを使用しています。だから私はコンテナビューを含むビューコントローラがあります。私はストーリーボードで2番目に小さいビューを持っています。このビューは埋め込みセグを介してそのコンテナに埋め込まれています。ここまでは順調ですね。動的にコンテナ表示を切り替える

これで、ユーザーがボタンをタップすると、そのコンテナビューの内容を動的に切り替えることができます。ボタンはメインの大きなビューに表示されます。同じサイズの別のビューコントローラを作成し、それに別のストーリーボードIDを与えました。

しかし、私はスイッチをコード化する方法を考えることができません。私は、そのコンテナのための単一の埋込みセグを作成することができます。

喜んでお寄せいただきありがとうございます。

答えて

39

コントローラの切り替えを行うには、カスタムコンテナビューコントローラAPIを使用する必要があります。次のコードは、その方法の1つを示しています。このプロジェクトでは、2つのコントローラーの間で切り替わるメインビューコントローラー(コンテナビューを持つコントローラー)でセグメント化されたコントロールを持っていました。 initialVCはIBに組み込まれているコントローラーで、substituteVCは私が切り替えようとしているコントローラーです。プロパティcontainerは、コンテナビューのIBOutletです。編集後

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.initialVC = self.childViewControllers.lastObject; 
    self.substituteVC = [self.storyboard instantiateViewControllerWithIdentifier:@"Substitute"]; 
    self.currentVC = self.initialVC; 
} 

-(IBAction)switchControllers:(UISegmentedControl *)sender { 

    switch (sender.selectedSegmentIndex) { 
     case 0: 
      if (self.currentVC == self.substituteVC) { 
       [self addChildViewController:self.initialVC]; 
       self.initialVC.view.frame = self.container.bounds; 
       [self moveToNewController:self.initialVC]; 
      } 
      break; 
     case 1: 
      if (self.currentVC == self.initialVC) { 
       [self addChildViewController:self.substituteVC]; 
       self.substituteVC.view.frame = self.container.bounds; 
       [self moveToNewController:self.substituteVC]; 
      } 
      break; 
     default: 
      break; 
    } 
} 


-(void)moveToNewController:(UIViewController *) newController { 
    [self.currentVC willMoveToParentViewController:nil]; 
    [self transitionFromViewController:self.currentVC toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionFlipFromLeft animations:nil 
          completion:^(BOOL finished) { 
           [self.currentVC removeFromParentViewController]; 
           [newController didMoveToParentViewController:self]; 
           self.currentVC = newController; 
          }]; 
} 

:あなたがいないアニメーションを持つ新しいコントローラに移動したい場合は

、あなたはそれが(これは私がケース1の下に持っていたコードを置換する)は、このように行うことができます。

[self addChildViewController:self.substituteVC]; 
[self.substituteVC didMoveToParentViewController:self]; 
self.substituteVC.view.frame = self.container.bounds; 
[self.container addSubview:self.substituteVC.view]; 
[self.currentVC removeFromParentViewController]; 
+0

こんにちは、ありがとう、それは素晴らしいです。一つのこと - 私が望む正確な結果(ストレートスワップ - アニメーションなし)を得るために、moveToNewControllerメソッドをduration:0に変更し、オプション:UIViewAnimationOptionTransitionNoneを変更しました。しかし、完成ブロック構造を含むいくつかのコードは冗長に見えます。ストレート(アニメーション化されていない)スワップの最終的なメソッドを記述するための簡単な方法はありますか? –

+0

@JamesWhite、私はアニメーションなしでそれを行う方法を示す私の答えを編集しました。 – rdelmar

+0

あなたはチャンピオンです。 –

4

rdelmar's answerあなたが2つの以上の子ビュー・コントローラを扱う場合は、配列に格納することをお勧めしますスウィフト構文に

override func viewDidLoad() { 
     super.viewDidLoad() 

     self.initialVC = self.childViewControllers.last 
     self.substituteVC = self.storyboard!.instantiateViewControllerWithIdentifier("Substitute") 
     self.currentVC = self.initialVC; 

} 
    @IBAction func switchControllers(sender: UISegmentedControl) { 
     switch sender.selectedSegmentIndex{ 
      case 0: 
       if (self.currentVC == self.substituteVC) { 
        self.addChildViewController(self.initialVC) 
        //self.initialVC.view.frame = self.containerView.bounds 
        moveToNewController(self.initialVC) 
       } 
      case 1: 
       if (self.currentVC == self.initialVC) { 
        self.addChildViewController(self.substituteVC) 
        //self.substituteVC.view.frame = self.containerView.bounds 
        moveToNewController(self.substituteVC) 
       } 
      default: 
      break; 
     } 
    } 

    func moveToNewController(newController : UIViewController){ 
     self.currentVC.willMoveToParentViewController(nil) 
     self.transitionFromViewController(
      self.currentVC!, 
      toViewController: newController, 
      duration: 0.2, 
      options: UIViewAnimationOptions.TransitionCrossDissolve, 
      animations: nil, 
      completion: { finished in 
       self.currentVC.removeFromParentViewController() 
       newController.didMoveToParentViewController(self) 
       self.currentVC = newController 
     }) 

    } 
0

を変換します。また、コンテナビューに新しいサブビューを追加するたびに、制約を適用する必要があります。ここでは、受け入れられた回答の修正版(Swift 2構文を使用しています):

import UIKit 

class FooBarViewController: UIViewController 
{ 
    // MARK: - IBOutlets 

    @IBOutlet weak var containerView: UIView! 

    // MARK: - Properties 

    var vcs = [UIViewController]() 
    var currentVC: UIViewController! 

    // MARK: - ViewController Lifecycle 

    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     vcs.append(childViewControllers.last!) 
     vcs.append(storyboard!.instantiateViewControllerWithIdentifier("FooViewControler"))  
     vcs.append(storyboard!.instantiateViewControllerWithIdentifier("BarViewController")) 
     currentVC = vcs[0] 

     for vc in vcs { 
      vc.view.frame = containerView.bounds 
     } 
    } 

    // MARK: - Methods 

    func switchToViewController(targetVC: UIViewController) 
    { 
     addChildViewController(targetVC) 
     currentVC.willMoveToParentViewController(nil) 

     transitionFromViewController(
      currentVC, 
      toViewController: targetVC, 
      duration: 0.0, // 0.3 
      options: .TransitionNone, // .TransitionCrossDissolve, 
      animations: nil, 
      completion: { finished in 
       self.currentVC.removeFromParentViewController() 
       targetVC.didMoveToParentViewController(self) 
       self.currentVC = targetVC 
       self.applyConstraints() 
     }) 
    } 

    func applyConstraints() 
    { 
     let viewsDict = ["newSubview": currentVC.view] 

     currentVC.view.translatesAutoresizingMaskIntoConstraints = false 

     containerView.addConstraints(
      NSLayoutConstraint.constraintsWithVisualFormat("H:|[newSubview]|", 
       options: NSLayoutFormatOptions(rawValue: 0), 
       metrics: nil, 
       views: viewsDict)) 

     containerView.addConstraints(
      NSLayoutConstraint.constraintsWithVisualFormat("V:|[newSubview]|", 
       options: NSLayoutFormatOptions(rawValue: 0), 
       metrics: nil, views: 
       viewsDict)) 
    } 

    // MARK: - IBActions 

    @IBAction func switchControllers(sender: UISegmentedControl) 
    { 
     let i = sender.selectedSegmentIndex 

     if currentVC != vcs[i] { 
      self.addChildViewController(vcs[i]) 
      switchToViewController(vcs[i]) 
     } 
    } 
} 
+0

「containerView」にView Controllerを追加するところはどこですか? – Satyam

関連する問題