我有十个不同的UIViewControllers
,每个right
都包含left
和pushController
按钮。右箭头将使下一个控制器位于前面,而左侧控制器将带来前一个控制器。我需要在控制器之间导航而不会丢失最后一个状态。但每次按下右箭头,都会出现一个新的控制器。我尝试过presentController
和{{1}}。我想在控制器之间自由导航而不会失去状态。你能指导一下怎么做吗?
答案 0 :(得分:4)
这样的问题非常广泛,Cocoa Touch提供了许多管理视图控制器的机制。我建议阅读Apple的View Controller Programming Guide for iOS,特别是Presenting View Controllers from Other View Controllers和Coordinating Efforts Between View Controllers部分。
话虽如此,这里有两种方法来管理多个UIViewControllers
的流量,同时保持每个{@ 1}的活动状态,以便所有状态(UI和基础数据)在其使用期间持续存在。这两种方法的关键是主视图控制器协调所有需要呈现的UIViewControllers
的切入和切换。
想象一下您的10个视图控制器1到10.如果用户始终首先呈现视图控制器编号1并且只能顺序地向前和向后导航,即用户无法直接在1到10之间导航,则此方法是合适的:
A UINavigationController
专门管理分层内容的导航。虽然我们可能不认为我们的10个视图控制器在概念上是分层的,但使用UINavigationController
允许我们利用其现有功能进行顺序导航。在此模型中,每个视图控制器都可以保留对序列中以下视图控制器的引用,呈现它并实现其委托回调以了解何时将其解除:
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
想象一下您的10个视图控制器1到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
答案 1 :(得分:2)
您需要维护一堆视图控制器,类似于UINavigationController的工作。当您向右移动时,您只需获取阵列中的下一个视图控制器并显示它,而不是创建要显示的新视图控制器
然后为了维护状态,每个视图控制器应该负责管理自己的状态,并且因为在视图被移除然后再次呈现之后,每次状态都相同时,您不会创建新的控制器。
e.g。而不是
UIViewController *controller = //new view controller
[self presentViewController:controller];
你应该做
UIViewController *controller = [self.controllers nextViewController];
[self presentNextController:controller];