要するに、ビューAとビューBを切り替えることができる2つのフルスクリーンビューが必要です。TabBar Controllerを使用できることは知っていますが、したくありません。フードの下で何が起こっているかを知るために、これが手作業でどのように行われるかを知りたい.
ルートコントローラーとして機能するUIViewControllerがあります。
@interface MyRootController : UIViewController {
IBOutlet UIView *contentView;
}
@property(nonatomic, retain) UIView *contentView;
@end
ContentViewは、サブビューとしてNibの「ビュー」に追加した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には次のようなすべてのメソッドがあります。
...等々。 Tab Bar Controllerなしで「自分の」方法で実行した場合、これらのメソッドは誰または何、またはどのように呼び出されますか?つまり、ViewControllerのクラスを割り当て、ビューが表示される場合、これらのメソッドの呼び出しに注意する必要がありますか? viewWillAppear、viewDidDisappear、またはviewDidLoadをどのように知るのですか? Tab Bar Controllerには、この「賢さ」がすべて隠されていると思います。それとも私は間違っていますか?
更新:私はそれをテストしました。 View Controller(たとえば、ViewControllerA)をリリースすると、viewDidDisappearでログメッセージが表示されません。 ViewControllerAを割り当てて初期化するときにのみ、viewDidLoadを取得します。しかし、それだけです。つまり、すべての兆候はUITabBarControllerの巧妙さを表しています;)そして、私はそれを複製する方法を理解する必要がありますよね?
最も単純な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];
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];
}
私が正しく理解していれば、あなたが達成しようとしていることは非常に簡単です。
アプリケーションデリゲートにUINavigationControllerを追加して、次の操作を行います。
[navigationController pushView:vcA];
デリゲートはそれに応じて呼び出されます。
そして、ビューをポップして別のビューをプッシュしたい場合:
[navigationController popViewControllerAnimated:true];
[navigationController pushView:vcB];
NavigationControllerの表示のみを使用したくない場合:
[navigationBar setHidden:YES];
NavigationBarは、UINavigationControllerに対応するUINavigationBarです。
これは古い問題かもしれませんが、最近同じ問題に遭遇し、機能するものを見つけるのに苦労しました。 2つの補完的なView Controllerを切り替えたいと思っていましたが、スイッチをアニメーション化して(アニメーションがうまく動作するように)、できればストーリーボードと互換性を持たせたいと思いました。
組み込みのトランジションを利用するために、UIViewの +transitionFromView:toView:duration:options:completion:
メソッドは美しく機能します。しかし、それはビュー間の遷移のみであり、View Controllerではありません。
ビューだけでなくView Controller全体に移行するには、カスタムのUIStoryboardSegue
を作成する方法があります。ストーリーボードを使用するかどうかにかかわらず、このアプローチにより、移行全体をカプセル化し、1つのビューコントローラーから次のビューコントローラーへの関連情報の受け渡しを管理できます。 UIStoryboardSegue
をサブクラス化し、単一のメソッド-perform
をオーバーライドするだけです。
リファレンス実装については、 RAFlipReplaceSegue
を参照してください。このアプローチを使用して作成した正確なカスタムセグエです。ボーナスとして、古いView ControllerがUINavigationController
スタックにある場合、新しいView Controllerに置き換えられます。