【问题标题】:UINavigationController not executing completionBlocks when presenting ViewController呈现 ViewController 时 UINavigationController 不执行完成块
【发布时间】:2012-12-29 21:22:36
【问题描述】:

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

有什么想法吗?

【问题讨论】:

  • mmm...情节变厚了...如果我注释掉viewControllerToPresent.modalPresentationStyle = UIModalPresentationCurrentContext; 行,则执行块,但模态显示全屏而不是在弹出框内。还是很烦

标签: ios uinavigationcontroller uikit presentmodalviewcontroller


【解决方案1】:

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

我创建了一个非常小的演示项目,它的架构是这样的:

  • ViewController - 主视图控制器

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

  • PopoverViewController - 显示在弹出窗口中

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

  • PopoverViewController2 - 在同一个弹出窗口中“模态”呈现

    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 不仅不能解决问题,还会导致视觉故障。)

【讨论】:

    【解决方案2】:

    UIModalPrsentationCurrentContext 样式仅在针对 iOS 3.2 或更高版本进行编译时可用。无法想象这是问题所在。

    UIModalPrsentationCurrentContext 的文档还说:

    在弹出框中呈现视图控制器时,仅当过渡样式为 UIModalTransitionStyleCoverVertical 时才支持此呈现样式。尝试使用不同的转换样式会触发异常。但是,如果父视图控制器不在弹出框中,您可以使用其他过渡样式(部分卷曲过渡除外)。

    这很奇怪。

    您是否有可能在 iPhone 和 iPad 上运行不同版本的 iOS?

    【讨论】:

    • 不...使用 iOS 6 SDK 构建并在两个设备上尝试 iOS 6。但是请阅读我对这个问题的评论,如果您注释掉 modalPresentationStyle 它按预期工作(但会占用整个屏幕,而不仅仅是所需的弹出窗口)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多