それぞれにとボタンUIViewControllers
が含まれている 10 種類があります。右矢印は次のコントローラを前面に移動し、左矢印は前のコントローラを移動します。最後の状態を失わずにコントローラー間を移動する必要があります。ただし、右矢印を押すたびに、新しいコントローラーが前面に出てきます。私は試してみました。状態を失うことなく、コントローラー間を自由に移動したい。それを行う方法を教えてもらえますか?right
left
pushController
presentController
2 に答える
このような質問は非常に幅広く、Cocoa Touchはビュー コントローラーを管理するための多数のメカニズムを提供します。Apple のiOS 用ビュー コントローラー プログラミング ガイド、特に他のビュー コントローラーからビュー コントローラーを提示するセクションとビュー コントローラー間の作業を調整するセクションを読むことをお勧めします。
UIViewControllers
そうは言っても、ここでは、使用中にすべての状態 (UI と基になるデータ) が保持されるように、それぞれを有効に保ちながら多数のフローを管理する 2 つの方法を紹介します。これらの両方のアプローチの鍵は、マスター ビュー コントローラーが、表示するUIViewControllers
必要があるすべてのものの切り替えを調整することです。
UINavigationController
1 から 10 までの 10 個のビュー コントローラーを想像してみてください。このアプローチは、ユーザーが常にビュー コントローラー番号 1 を最初に提示され、それらを順番に前後にしか移動できない場合に適しています。つまり、ユーザーは 1 と 10 の間を直接移動することはできません。
AUINavigationController
は、階層コンテンツのナビゲーションの管理を専門としています。概念的には 10 個のビュー コントローラーを階層的なものとは考えないかもしれませんが、を使用するUINavigationController
と、既存の機能をシーケンシャル ナビゲーションに活用できます。このモデルでは、各View Controllerは、シーケンス内の次のView Controllerへの参照を保持し、それを提示し、デリゲートコールバックを実装して、いつそれを閉じるかを知る責任があります。
コード
MYPresentationViewController.h
@class MYPresentationViewController;
// The MYPresentationViewControllerDelegate allows the presenting view controller to know when the presented view controller (next highest in the presentation stack) has been dismissed.
@protocol MYPresentationViewControllerDelegate <NSObject>
- (void)viewControllerDidFinish:(MYPresentationViewController *)viewController;
@end
@interface MYPresentationViewController : UIViewController <MYPresentationViewControllerDelegate>
// The next view controller in the sequence.
@property (strong, nonatomic) MYPresentationViewController *nextViewController;
// The delegate responsible for showing and dismissing this view controller.
@property (assign) id<MYPresentationViewControllerDelegate> delegate;
@end
MYPresentationViewController.m
#import "MYPresentationViewController.h"
@implementation MYPresentationViewController
#pragma mark - Custom Property Assessors
// Returns the next view controller in the sequence. Creates and configures it if it doesn't already exist.
- (MYPresentationViewController *)nextViewController
{
if (_nextViewController == nil)
{
_nextViewController = [[MYPresentationViewController alloc] initWithNibName:@"MYPresentationViewController" bundle:nil];
_nextViewController.delegate = self;
}
return _nextViewController;
}
#pragma mark - UI Control Event Handlers
- (IBAction)leftButtonPressed:(UIButton *)sender
{
// Tell the delegate this view controller is ready to be dismissed.
[self.delegate viewControllerDidFinish:self];
}
- (IBAction)rightButtonPressed:(UIButton *)sender
{
// Present the next view controller.
[self.navigationController pushViewController:self.nextViewController animated:YES];
}
#pragma mark - MYPresentationViewControllerDelegate
- (void)viewControllerDidFinish:(MYPresentationViewController *)viewController
{
// Dismiss the next view controller to return to this one.
[self.navigationController popViewControllerAnimated:YES];
}
@end
カスタムマスターコントローラー
1 から 10 までの 10 個のビュー コントローラーを想像してみてください。このアプローチは、最初にどちらの端 (1 または 10) にもないビュー コントローラーをユーザーに提示できる場合、および/またはユーザーが 1 と 10 の間を直接移動できる場合に適しています。循環ナビゲーション:
提示する必要があるすべてのものの切り替えを監視し、容易にする独自の「マスターコントローラー」を作成することUIViewControllers
で、任意の方法でナビゲーションを実装できます。このモデルでは、マスター ビュー コントローラーは、表示されるすべてのビュー コントローラーへの参照を処理し、それらを表示してデリゲート コールバックを実装する役割を担います。
コード
MYMasterViewController.h
#import "MYPresentationViewController.h"
@interface MYMasterViewController : UIViewController <MYPresentationViewControllerDelegate>
// The collection of view controllers to be presented.
@property (strong, nonatomic) NSArray *allViewControllers;
@end
MYMasterViewController.m
#import "MYMasterViewController.h"
@implementation MYMasterViewController
...
// Create 10 view controllers;
- (void)createViewControllers
{
NSMutableArray *allViewControllers = [NSMutableArray arrayWithCapacity:10];
// Create our 10 view controllers.
for (int i = 0; i < 10; i++)
{
MYPresentationViewController *viewController = [[MYPresentationViewController alloc] initWithNibName:@"MYPresentationViewController" bundle:nil];
viewController.delegate = self;
viewController.index = i;
[allViewControllers addObject:viewController];
}
self.allViewControllers = allViewControllers;
}
// Display first view controller, could be any in the sequence.
- (void)displayViewController
{
MYPresentationViewController *firstViewController = [self.allViewControllers objectAtIndex:0];
[self presentViewController:firstViewController animated:NO completion:nil];
}
#pragma mark - MYPresentationViewControllerDelegate
- (void)viewController:(MYPresentationViewController *)viewController didDismissWithButton:(kButtonPressed)button
{
[self dismissViewControllerAnimated:NO completion:nil];
// Determine the next view controller to display.
NSInteger index = viewController.index;
index += button == kButtonPressedLeft ? -1 : 1;
if (index < 0) {
index = self.allViewControllers.count - 1;
}
else if (index >= self.allViewControllers.count) {
index = 0;
}
MYPresentationViewController *nextViewController = [self.allViewControllers objectAtIndex:index];
[self presentViewController:nextViewController animated:NO completion:nil];
}
@end
MYPresentationViewController.h
@class MYPresentationViewController;
// Enumeration used to give a more descriptive code association with the presentation view controller's navigation button options.
typedef enum {
kButtonPressedLeft,
kButtonPressedRight,
} kButtonPressed;
// The MYPresentationViewControllerDelegate allows the presenting view controller to know when the presented view controller has been dismissed and with what button i.e. (left or right).
@protocol MYPresentationViewControllerDelegate <NSObject>
- (void)viewController:(MYPresentationViewController *)viewController didDismissWithButton:(kButtonPressed)button;
@end
@interface MYPresentationViewController : UIViewController
// The index of this view controller in relation to 10.
@property (assign) NSInteger index;
// The delegate responsible for showing and dismissing this view controller.
@property (assign) id<MYPresentationViewControllerDelegate> delegate;
@end
MYPresentationViewController.m
#import "MYPresentationViewController.h"
@implementation MYPresentationViewController
#pragma mark - UI Control Event Handlers
- (IBAction)leftButtonPressed:(UIButton *)sender
{
// Tell the delegate this view controller is ready to be dismissed.
[self.delegate viewController:self didDismissWithButton:kButtonPressedLeft];
}
- (IBAction)rightButtonPressed:(UIButton *)sender
{
// Tell the delegate this view controller is ready to be dismissed.
[self.delegate viewController:self didDismissWithButton:kButtonPressedRight];
}
@end
UINavigationController と同様に、View Controller のスタックを維持する必要があります。右に移動すると、表示する新しいView Controllerを作成する代わりに、配列内の次のView Controllerを取得して表示するだけです
次に、状態を維持するには、各View Controllerが独自の状態を管理する必要があります。ビューが削除されてから再度表示された後、状態が同じになるたびに新しいコントローラーを作成しないためです。
たとえば、代わりに
UIViewController *controller = //new view controller
[self presentViewController:controller];
やったほうがいい
UIViewController *controller = [self.controllers nextViewController];
[self presentNextController:controller];