iOS 5の世界にいて、さまざまなView Controller間を移動したい場合は、ViewControllerContainmentを追求することをお勧めします。または、WWDC2011セッション102を確認してください。
ビューコントローラの包含は、基本的に、複数の子コントローラ間のナビゲーションを管理する親ビューコントローラがあることを前提としています。あなたの場合、親ビューは、ボタンが付いたナビゲーションバーを備えたビューになります。
アップデート:
封じ込めを追求する場合は、ボタンが付いたナビゲーションバーを持つ親ビューコントローラーを作成できます。そのビューをロードすると、最初の子ビューを追加できます。したがってviewDidLoad
、次のようになります。
- (void)viewDidLoad
{
[super viewDidLoad];
// this is my model, where I store data used by my view controllers
_model = [[MyModel alloc] init];
// let's create our first view controller
OneViewController *controller = [[OneViewController alloc] initWithNibName:@"OneViewController" bundle:nil];
// pass it our model (obviously, `model` is a property that I've set up in my child controllers)
controller.model = _model;
// let's put the new child in our container and add it to the view
[self addChildViewController:controller];
[self configureChild:controller];
[self.view addSubview:controller.view];
[controller didMoveToParentViewController:self];
// update our navigation bar title and the label of the button accordingly
[self updateTitles:controller];
}
configureChild
最終的な構成を行うだけです。便宜上、私はIB(この場合はと呼ばれるchildView
)で設定したUIViewを頻繁に使用します。これは、フレームの設定に使用します。これにより、手動でフレームを作成するという世界から抜け出すことができますが、あなたが望む方法でそれを行うことができます:
- (void)configureChild:(UIViewController *)controller
{
// configure it to be the right size (I create a childView in IB that is convenient for setting the size of the views of our child view controllers)
controller.view.frame = self.childView.frame;
}
これは、ナビゲーションバーのボタンをタッチした場合のアクションです。最初のコントローラーを使用している場合は、2番目のコントローラーをセットアップします。2番目のコントローラーを使用している場合は、最初のコントローラーをセットアップします。
- (IBAction)barButtonTouchUpInside:(id)sender
{
UIViewController *currentChildController = [self.childViewControllers objectAtIndex:0];
if ([currentChildController isKindOfClass:[OneViewController class]])
{
TwoViewController *newChildController = [[TwoViewController alloc] initWithNibName:@"TwoViewController" bundle:nil];
newChildController.model = _model;
[self transitionFrom:currentChildController To:newChildController];
}
else if ([currentChildController isKindOfClass:[TwoViewController class]])
{
OneViewController *newChildController = [[OneViewController alloc] initWithNibName:@"OneViewController" bundle:nil];
newChildController.model = _model;
[self transitionFrom:currentChildController To:newChildController];
}
else
NSAssert(FALSE, @"Unknown controller type");
}
これにより、基本的な移行(さまざまな封じ込め関連の呼び出しを含む)が行われます。
- (void)transitionFrom:(UIViewController *)oldController To:(UIViewController *)newController
{
[self addChildViewController:newController];
[self configureChild:newController];
[self transitionFromViewController:oldController
toViewController:newController
duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self updateTitles:newController];
}
completion:^(BOOL finished){
[oldController willMoveToParentViewController:nil];
[oldController removeFromParentViewController];
[newController didMoveToParentViewController:self];
}];
}
このメソッドは、選択された子に基づいて、親ビューコントローラーのナビゲーションバーにタイトルを設定するだけです。また、他のコントローラーを参照するためのボタンを設定します。
- (void)updateTitles:(UIViewController *)controller
{
if ([controller isKindOfClass:[OneViewController class]])
{
self.navigationItemTitle.title = @"First View Controller"; // current title
self.barButton.title = @"Two"; // title of button to take me to next controller
}
else if ([controller isKindOfClass:[TwoViewController class]])
{
self.navigationItemTitle.title = @"Second View Controller"; // current title
self.barButton.title = @"One"; // title of button to take me to next controller
}
else
NSAssert(FALSE, @"Unknown controller type");
}
これはすべて、コントローラー間をジャンプするときにコントローラーを作成および破棄することを前提としています。私は通常これを行いますが、モデルオブジェクトを使用してデータを保存するため、必要なデータを保持します。
「UIViewを再割り当てして置き換えることなく」これを実行したくないとおっしゃいました。その場合は、上記のコードを変更して、両方の子View Controllerを事前に作成し、トランジションを変更して、それらの間をジャンプすることもできます。
- (void)viewDidLoad
{
[super viewDidLoad];
// this is my model, where I store data used by my view controllers
_model = [[MyModel alloc] init];
// let's create our first view controller
_controller0 = [[OneViewController alloc] initWithNibName:@"OneViewController" bundle:nil];
_controller0.model = _model;
[self addChildViewController:_controller0];
[self configureChild:_controller0];
[_controller0 didMoveToParentViewController:self];
// let's create our second view controller
_controller1 = [[OneViewController alloc] initWithNibName:@"OneViewController" bundle:nil];
_controller1.model = _model;
[self addChildViewController:_controller1];
[self configureChild:_controller1];
[_controller1 didMoveToParentViewController:self];
// let's add the first view and update our navigation bar title and the label of the button accordingly
_currentChildController = _controller0;
[self.view addSubview:_currentChildController.view];
[self updateTitles:_currentChildController];
}
- (void)transitionFrom:(UIViewController *)oldController To:(UIViewController *)newController
{
[self transitionFromViewController:oldController
toViewController:newController
duration:0.5
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self updateTitles:newController];
}
completion:^(BOOL finished){
_currentChildController = newController;
}];
}
- (IBAction)barButtonTouchUpInside:(id)sender
{
UIViewController *newChildController;
if ([_currentChildController isKindOfClass:[OneViewController class]])
{
newChildController = _controller1;
}
else if ([_currentChildController isKindOfClass:[TwoViewController class]])
{
newChildController = _controller0;
}
else
NSAssert(FALSE, @"Unknown controller type");
[self transitionFrom:_currentChildController To:newChildController];
}
私はそれを両方の方法で見たので、あなたはあなたのために働くことは何でもすることができます。