iOS:使用动画推送视图控制器只能工作一次

时间:2013-03-30 16:55:16

标签: ios pushviewcontroller

我正在为我的一个拥有API的应用创建一个iPhone客户端。我正在使用GTMOAuth2库进行身份验证。该库负责使用正确的URL为我打开Web视图。但是我必须自己推动视图控制器。让我向您展示一些代码,以使事情更清晰:

- (void)signInWithCatapult
{
    [self signOut];

    GTMOAuth2ViewControllerTouch *viewController;
    viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithAuthentication:[_account catapultAuthenticaiton]
                                                                 authorizationURL:[NSURL URLWithString:kCatapultAuthURL]
                                                                 keychainItemName:kCatapultKeychainItemName
                                                                         delegate:self
                                                                 finishedSelector:@selector(viewController:finishedWithAuth:error:)];

    [self.navigationController pushViewController:viewController animated:YES];
}

我有一个“加”/“添加”按钮,我动态地添加到视图中并指向该方法:

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(signInWithCatapult)];

当我按下“添加”按钮时,应该发生的事情是用动画打开Web视图,然后将帐户添加到填充表视图的accounts实例变量中。如果我添加一个帐户,这可以正常工作,但是当我尝试添加第二个帐户时,屏幕变黑并且控制台中出现两个错误:

nested pop animation can result in corrupted navigation bar

Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

我发现避免此问题的唯一方法是在按下视图控制器时禁用动画。

我做错了什么?

3 个答案:

答案 0 :(得分:0)

一旦你进去,你是否尝试过以下解雇?

[self dismissViewControllerAnimated:YES completion:nil];

答案 1 :(得分:0)

典型情况

  1. push内的popviewWillAppear:个控制器或类似方法。

  2. 您覆盖viewWillAppear:(或类似方法)但未致电[super viewWillAppear:]

  3. 您正在同时开始两个动画,例如运行动画pop,然后立即运行动画push。然后动画发生碰撞。在这种情况下,必须使用[UINavigationController setViewControllers:animated:]

答案 2 :(得分:0)

当我试图在视图控制器出现之前弹出它时,我收到了nested pop animation can result in corrupted navigation bar消息。覆盖viewDidAppear以在UIViewController子类中设置一个标志,指示视图已出现(记得也要调用[super viewDidAppear])。在弹出控制器之前测试该标志。如果视图尚未出现,您可能需要设置另一个标记,指示您需要在viewDidAppear内立即弹出视图控制器,一旦它出现。像这样:

@interface MyViewController : UIViewController {
    bool didAppear, needToPop;
}

...并在@implementation ...

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    didAppear = YES;
    if (needToPop)
        [self.navigationController popViewControllerAnimated:YES];
}

- (void)myCrucialBackgroundTask {
    // this task was presumably initiated when view was created or loaded....
    ...
    if (myTaskFailed) {  // o noes!
        if (didAppear)
            [self.navigationController popViewControllerAnimated:YES];
        else
            needToPop = YES;
    }
}

重复的popViewControllerAnimated电话有点难看,但这是我能够在目前疲惫状态下工作的唯一方法。