Edycja: „prawidłowy” mechanizm zrobić w iOS5 + byłoby użyć metody – dismissViewControllerAnimated:completion:
i przedstawia sekwencyjnego sterowania widok z bloku realizacji.
viewcontroller który jest pokazany modalne, będzie mieć swoje viewDidDisappear: animowany: metoda zwana po modalnym zwolnienie animacja jest zakończona.AFIK to jedyne miejsce, w które można podpiąć, by zainicjować kolejny presentModalViewController: animated: call.
Mam klasę, której używam do prezentacji modalnych kontrolerów widoku i implementuje logikę, której szukasz, przez wywołanie zwrotne do prezentującego kontrolera widoku po zakończeniu zwolnienia. Aby użyć tej klasy, po prostu przydzielaj/init instancję i prezentuj przy użyciu zwykłego presentViewController: animated: call. Wdrożenie następującą metodę na kontrolerze widoku prezentowanie:
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
To będzie nazywany naraz modalna kontroler widok zniknął, a można przedstawić nowy kontroler modalne widoku w tym czasie.
Jedną miłą rzeczą zbyt - ponieważ ta klasa jest specjalizacja UINavigationController można skonfigurować navigationBar on/off, jak chcesz. Klasa ma również wbudowaną logikę, która pokazuje przycisk odrzucania, tak jak lubisz.
Oto definicja klasy:
@protocol TSModalViewControllerDelegate
- (void) modalViewControllerDidDismiss: (UIViewController*) modalViewController;
@end
@interface TSModalViewController : UINavigationController
{
UIViewController* _originalParentViewController;
}
@property BOOL dismissButtonHidden;
- (id) initWithViewController: (UIViewController*) vc;
- (id) initWithClass: (Class) c;
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
@end
i wdrożenie klasa:
@implementation TSModalViewController
@synthesize dismissButtonHidden;
- (id) initWithViewController: (UIViewController *)vc
{
return [super initWithRootViewController: vc];
}
- (id) initWithClass:(Class)c
{
UIViewController* vc = [[[c alloc] init] autorelease];
return [self initWithViewController: vc];
}
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
UIViewController* vc = [[[c alloc] initWithNibName:nibNameOrNil bundle:nibBundleOrNil] autorelease];
return [self initWithViewController: vc];
}
- (void) viewDidAppear: (BOOL) animated
{
[super viewDidAppear: animated];
[_originalParentViewController release];
_originalParentViewController = [self.parentViewController retain];
if (!self.dismissButtonHidden)
{
UIBarButtonItem* dismissButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemStop
target: self
action: @selector(onDismiss:)] autorelease];
UIViewController* rootViewController = [self.viewControllers objectAtIndex:0];
rootViewController.navigationItem.leftBarButtonItem = dismissButton;
self.navigationBarHidden = NO;
}
}
- (void) viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear: animated];
if ([_originalParentViewController respondsToSelector: @selector(modalViewControllerDidDismiss:)])
{
[_originalParentViewController performSelector: @selector(modalViewControllerDidDismiss:) withObject: self];
}
}
- (void) dismissModalViewControllerAnimated:(BOOL)animated
{
return [self.parentViewController dismissModalViewControllerAnimated: animated];
}
- (void) onDismiss: (id) sender
{
[self.parentViewController dismissModalViewControllerAnimated: YES];
}
- (void) didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void) viewDidUnload
{
[super viewDidUnload];
}
- (void)dealloc
{
[_originalParentViewController release];
[super dealloc];
}
@end
, a oto jak można go używać (w kontekście jakiegoś normalnego widoku kontrolera):
- (void) onShowIt:(id)sender
{
TSModalViewController* mvc = [[[TSModalViewController alloc] initWithClass: [MyModalViewController class] nibName: @"MyModalViewController" bundle:nil] autorelease];
mvc.dismissButtonHidden = YES; // set to no if you don't want an "automatic" close button
[self presentModalViewController: mvc animated: YES];
}
i tutaj jest metoda wywołania zwrotnego, która przedstawia nowy kontroler widoku modalnego:
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
{
MyModalViewController* vc = [[[MyModalViewController alloc] initWithNibName: @"MyModalViewController" bundle:nil] autorelease];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
TSModalViewController* mvc = [[[TSModalViewController alloc] initWithViewController: vc] autorelease];
[self presentModalViewController: mvc animated: YES];
}
Dlaczego nie wystarczy użyć na Modal View Controller, który zmienia swój pogląd? Dwa kontrolery widoku modalnego z rzędu byłyby trochę denerwujące. – bpapa
Jeśli są "następujące po sobie", rozważ użycie nawigacji. –
Czy jesteś w 100% pewien, że odrzucenie pierwszego widoku modalnego i otwarcie drugiego są wykonywane w kontekście głównego wątku? – yonel