UINavigationController在呈现ViewController时不执行completionBlocks

时间:2013-01-15 17:36:23

标签: ios uinavigationcontroller uikit presentmodalviewcontroller

这个很棘手。我有一个UINavigationController的子类,它覆盖了pop / push和present / dismiss方法。如果UINavigationController子类包含在弹出窗口中,我在这里自定义行为以设置正确的大小。没有什么太花哨,但我这样做是为了不写我所有ViewControllers的子类并使用Autolayout。

但是,presentViewController:animated:completion:dismissViewControllerAnimated:completion:的完成块未被执行。这是一个奇怪的部分:iPhone上的完全相同的代码可以正常工作,但在iPad上没有执行块。这是一个代码示例。

@interface SBNavigationController : UINavigationController

@end

@implementation SBNavigationController

- (void) presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if ([viewControllerToPresent isKindOfClass:[UINavigationController class]])
    {
        UINavigationController *nav = (UINavigationController *) viewControllerToPresent;
        [nav.topViewController setContentSizeForViewInPopover:kFullSizePopover];

    } else
    {
        [viewControllerToPresent setContentSizeForViewInPopover:kFullSizePopover];
    }

    viewControllerToPresent.modalPresentationStyle = UIModalPresentationCurrentContext;
    [super presentViewController:viewControllerToPresent animated:flag completion:completion];
}

- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion ;
{
    [super dismissViewControllerAnimated:flag completion:completion];
}
@end

使用它的代码就是:

@implementation SBInviteFBContactViewController

...

- (void) createInviteByMailViewController
{
    SBInviteMailViewController *mailInvite = [[SBInviteMailViewController alloc] initWithDelegate:self userInfo:_userInfo];

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mailInvite];

    [self.navigationController presentViewController:navController
                                            animated:YES
                                          completion:^{

                                              NSLog(@"presentViewController:");

                                          }];

}

#pragma mark SBInviteMailProtocol

- (void) invitedMailContacts:(NSArray *)contacts;
{
    [self.navigationController dismissViewControllerAnimated:YES
                                                  completion:^{
                                                      NSLog(@"animation Ended");
                                                      if (contacts) {
                                                          [self.delegate invitedMailContact:contacts];
                                                          [self popViewControllerAnimated:YES];
                                                      }
                                                  }];
}

...

@end

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这似乎是巨大的错误。请向Apple报告(我也将这样做)。我找到了自己的方式,因为我自己发现了同样的错误,并进行了谷歌搜索,看看是否有其他人在谈论它。

我创建了一个非常小的演示项目,其架构如下:

  • ViewController - 主视图控制器

    它的视图包含一个按钮Tap Me。

  • PopoverViewController - 在popover中显示

    当你点击主ViewController中的Tap Me时,它会创建一个带有 vc的UIPopoverController,PopoverViewController作为其内容视图控制器;它的视图也包含一个按钮Tap Me。

  • PopoverViewController2 - 在同一个popover中呈现“modally”

    PopoverViewController2将modalPresentationStyle设置为UIModalPresentationCurrentContext,因此它可以显示在弹出框内。当您点击弹出框中的Tap Me时,PopoverViewController会调用presentViewController:...

以下是代码:

- (IBAction)doTapMe:(id)sender {
    NSLog(@"about to present view controller");
    [self presentViewController:[PopoverViewController2 new] animated:YES completion:^{
        NSLog(@"in completion handler"); // never called!
    }];
    NSLog(@"did present view controller");
}

日志显示“即将呈现视图控制器”和“确实呈现视图控制器”,但“完成处理程序”中永远不会出现,即使“模态”视图控制器的视图出现在弹出框中也不错。

(此外,更改为animated:NO不仅无法解决问题,还会导致视觉故障。)