显示连续modalViews的正确方法

Tia*_*tos 9 iphone animated dismiss modalviewcontroller

我有两个视图需要以模态方式显示,一个接一个.如果我们连续解雇和显示,这不起作用,如下所示:

[rootController dismissModalViewControllerAnimated: YES];
[rootController presentModalViewController: psvc animated: YES];
Run Code Online (Sandbox Code Playgroud)

第二个模态视图根本没有显示出来.

我见过一个像这样的修复:

[rootController dismissModalViewControllerAnimated: YES];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[self performSelector: @selector(seekModal) withObject: nil afterDelay: 0.5];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
Run Code Online (Sandbox Code Playgroud)

问题是这不会一直有效(所需的延迟有时是优越的).

另一个可能的解决方法是消除动画:

[rootController dismissModalViewControllerAnimated: NO];
[rootController presentModalViewController: psvc animated: YES];
Run Code Online (Sandbox Code Playgroud)

但我真的很想保留动画,以保持第一个模态不受影响的感觉.有什么建议?

Tom*_*ift 17

编辑: 在iOS5 +中执行此操作的"正确"机制是使用该– dismissViewControllerAnimated:completion:方法,并从完成块显示顺序视图控制器.


以模态方式显示的viewcontroller将具有viewDidDisappear:animated:方法,一旦模态解除动画完成就会调用.AFIK这是唯一可以挂钩以启动后续presentModalViewController:animated:call的地方.

我有一个用于呈现模态视图控制器的类,它通过在解雇完成后回显到呈现视图控制器来实现您正在寻找的逻辑.要使用这个类,只需使用普通的presentViewController:animated:call来分配/初始化一个实例并呈现.在呈现视图控制器上实现以下方法:

- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
Run Code Online (Sandbox Code Playgroud)

这将在模态视图控制器消失时立即调用,此时您可以呈现新的模态视图控制器.

也是一件好事 - 因为这个类是UINavigationController的特化,你可以根据需要配置navigationBar的开/关.该类还具有内置逻辑,可以根据需要显示关闭按钮.

这是类定义:

@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
Run Code Online (Sandbox Code Playgroud)

和类实现:

@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
Run Code Online (Sandbox Code Playgroud)

并且,以下是如何使用它(在一些普通视图控制器的上下文中):

- (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];
}
Run Code Online (Sandbox Code Playgroud)

并且,这里是解雇回调方法,它提出了一个新的模态视图控制器:

- (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];
}
Run Code Online (Sandbox Code Playgroud)