2009-05-26 12 views
52

要約:私はビューAとビューBの間で切り替えることができる2つのフルスクリーン表示をしたいと思います。私はタブバーコントローラを使うことができますが、私はしたくありません。私はこれがどのように手で行われているのかを知りたいと思っています。View Controller:ビューをプログラムで切り替えるにはどうすればよいですか?

Iは、ルート・コントローラとして動作するのUIViewControllerた:

@interface MyRootController : UIViewController { 
    IBOutlet UIView *contentView; 
} 
@property(nonatomic, retain) UIView *contentView; 

@end 

contentViewは私はペン先の「ビュー」のサブビューとして追加のUIViewにフックアップされています。これは緑色で、全画面表示です。正常に動作します。

次に、他の2つのView Controllerも同じように作成しました。 ViewControllerAおよびViewControllerB。 ViewControllerAは青い背景を持ち、ViewControllerBは黒の背景を持っています。どちらがアクティブかを確認するだけです。

ので、myRootControllerの実装では、私はこれを行う:ところで

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    ViewControllerA *vcA = [[ViewControllerA alloc] initWithNib]; 
    [self.contentView addSubview:vcA.view]; 

    [cvA release]; 
} 

を、-initWithNib方法は、次のようになります。作品

- (id)initWithNib { // Load the view nib 
    if (self = [super initWithNibName:@"ViewA" bundle:nil]) { 
     // do ivar initialization here, if needed 
    } 
    return self; 
} 

を。私はViewControllerAから私がアプリケーションを起動すると、ビューが表示されます。しかし、今大きな問題があります:View Controllerは通常、以下のようなメソッドをすべて持っています:

  • (void)viewWillAppear:(BOOL)animated;
  • (void)viewDidDisappear:(BOOL)animated;
  • (void)viewDidLoad;

...など。タブ・バー・コントローラーを使わずに「私」のやり方をすれば、誰が何を、どのように、あるいはそれらのメソッドを呼び出すことができますか?つまり、ViewControllerのクラスを割り当ててビューを表示すると、それらのメソッドを呼び出す際に気を配らなければなりませんか? viewWillAppear、viewDidDisappear、またはviewDidLoadがどのように知っていますか?私は、Tab Bar Controllerはこの「賢さ」をフードの下にすべて持っていると信じています。または私は間違っていますか?

更新:私はそれをテストしました。 View Controller(たとえば:ViewControllerA)を解放すると、viewDidDisappearにログメッセージは表示されません。 ViewControllerAを割り当てて初期化するときだけ、私はviewDidLoadを取得します。しかし、それだけです。だから、すべての印はUITabBarControllerの巧みさを表しています;)それを複製する方法を理解する必要があります。

答えて

39

最も簡単なremoveFromSuperview/insertSubviewから始めて少しずつコードを追加できます。


//SwitchViewController.h 
#import 
@class BlueViewController; 
@class YellowViewController; 

@interface SwitchViewController : UIViewController { 
    IBOutlet BlueViewController *blueViewController; 
    IBOutlet YellowViewController *yellowViewController; 
} 
- (IBAction)switchViews:(id)sender; 
@property (nonatomic, retain) BlueViewController *blueViewController; 
@property (nonatomic, retain) YellowViewController *yellowViewController; 
@end 

//1. remove yellow view and insert blue view 
- (IBAction)switchViews:(id)sender { 
    if(self.blueViewController.view.superview == nil) 
    { 
     [yellowViewController.view removeFromSuperview]; 
     [self.view insertSubview:blueViewController.view atIndex:0]; 
    } 
} 

//2. appear=insert, disappear=remove 
if(blueViewController.view.superview == nil) 
{ 
    [blueViewController viewWillAppear:YES]; 
    [yellowViewController viewWillDisappear:YES]; 

    [yellowViewController.view removeFromSuperview]; 
    [self.view insertSubview:self.blueViewController.view atIndex:0]; 

    [yellowViewController viewDidDisappear:YES]; 
    [blueViewController viewDidAppear:YES]; 
} 

//3. now add animation 
[UIView beginAnimations:@"View Flip" context:nil]; 
[UIView setAnimationDuration:1.25]; 
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 
//blue view will appear by flipping from right 
if(blueViewController.view.superview == nil) 
{ 
    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight 
          forView:self.view cache:YES]; 

    [blueViewController viewWillAppear:YES]; 
    [yellowViewController viewWillDisappear:YES]; 

    [yellowViewController.view removeFromSuperview]; 
    [self.view insertSubview:self.blueViewController.view atIndex:0]; 

    [yellowViewController viewDidDisappear:YES]; 
    [blueViewController viewDidAppear:YES]; 
} 
[UIView commitAnimations]; 

21

私が正しく理解すれば、達成しようとしていることはかなり簡単です。

ちょうどあなたのアプリケーションデリゲートにUINavigationControllerを追加して実行します。

[navigationController pushView:vcA]; 

参加者はそれに応じて呼び出されます。

  • (無効)viewWillAppear:(BOOL)アニメーション。
  • (void)viewDidDisappear:(BOOL)animated;
  • (void)viewDidLoad;

そして、あなたは、ビューをポップとプッシュしたいときに、別の1:あなたが示すnavigationControllerをしたくない場合は

[navigationController popViewControllerAnimated:true]; 
[navigationController pushView:vcB]; 

だけ使用します。navigationBarはUINavigationBarある

[navigationBar setHidden:YES]; 

あなたのUINavigationControllerに対応します。

+0

いいえ、私はナビゲーションやタブバーは必要ありません;)私はちょうどボタン "Bに行く"と、他の "Aに行く"と裸のビューが欲しいです。または、上にそのナビゲーションバーを持たない方法がありますか? – Thanks

+0

画面に表示したくない場合は、ナビゲーションバーを非表示にすることができます。私は情報で答えを更新します。 –

50

「iPhone開発の基礎」の第6章では、ビューを切り替えるという素晴らしい例があります。 http://iphonedevbook.com/

SwitchViewControllerにはプログラムでビューを変更するコードがあります。


- (IBAction)switchViews:(id)sender 
{ 

    if (self.yellowViewController == nil) 
    { 
     YellowViewController *yellowController = [[YellowViewController alloc] 
       initWithNibName:@"YellowView" bundle:nil]; 
     self.yellowViewController = yellowController; 
     [yellowController release]; 
    } 

    [UIView beginAnimations:@"View Flip" context:nil]; 
    [UIView setAnimationDuration:1.25]; 
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 

    UIViewController *coming = nil; 
    UIViewController *going = nil; 
    UIViewAnimationTransition transition; 

    if (self.blueViewController.view.superview == nil) 
    { 
     coming = blueViewController; 
     going = yellowViewController; 
     transition = UIViewAnimationTransitionFlipFromLeft; 
    } 
    else 
    { 
     coming = yellowViewController; 
     going = blueViewController; 
     transition = UIViewAnimationTransitionFlipFromRight; 
    } 

    [UIView setAnimationTransition: transition forView:self.view cache:YES]; 
    [coming viewWillAppear:YES]; 
    [going viewWillDisappear:YES]; 
    [going.view removeFromSuperview]; 
    [self.view insertSubview: coming.view atIndex:0]; 
    [going viewDidDisappear:YES]; 
    [coming viewDidAppear:YES]; 

    [UIView commitAnimations]; 

} 
+13

+1を参考にして参考にしてください(ちょうど@iPhoneyが忘れたもの)。 – matm

2

これは、古い問題かもしれないが、私は最近、同じ問題に出くわしたと苦労働いていた何かを見つけていました。私は2つの補完的なView Controllerを切り替えたいと思っていましたが、スイッチをアニメーション化したい(アニメーションはうまくいきました)ので、できるだけストーリーボードと互換性を持たせたいと思っていました。

組み込みのトランジションを利用するために、UIViewの+transitionFromView:toView:duration:options:completion:メソッドは美しく機能します。しかし、ビューコントローラ間ではなく、ビュー間でのみ遷移します。

ビュー全体だけでなく、ビュー全体を移動するには、カスタムを作成するUIStoryboardSegueが必要です。ストーリーボードを使用するかどうかに関わらず、このアプローチを使用すると、トランジション全体をカプセル化して、1つのView Controllerから次のView Controllerへの関連情報の受け渡しを管理できます。 UIStoryboardSegueをサブクラス化し、単一のメソッド-performをオーバーライドするだけです。

参考実装については、このアプローチを使用してまとめた正確なカスタムセグメントのRAFlipReplaceSegueを参照してください。ボーナスとして、それはUINavigationControllerスタック内にある場合、古いビューコントローラを新しいビューコントローラに置き換えます。

関連する問題