【问题标题】:Multiple modal views tap to dismiss多个模态视图点击以关闭
【发布时间】:2012-06-17 09:44:34
【问题描述】:

我设置了一种机制,可以通过点击视图外部来关闭模态视图控制器。设置如下:

- (void)viewDidAppear:(BOOL)animated
{
    UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapBehind:)];
    [recognizer setNumberOfTapsRequired:1];
    recognizer.cancelsTouchesInView = NO; //So the user can still interact with controls in the modal view
    [self.view.window addGestureRecognizer:recognizer];

}

- (void)handleTapBehind:(UITapGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateEnded)
    {
        CGPoint location = [sender locationInView:nil]; //Passing nil gives us coordinates in the window

        //Then we convert the tap's location into the local view's coordinate system, and test to see if it's in or outside. If outside, dismiss the view.

        if (![self.view pointInside:[self.view convertPoint:location fromView:self.view.window] withEvent:nil]) 
        {
            [self dismissModalViewControllerAnimated:YES];
            NSLog(@"There are %d Gesture Recognizers",[self.view.window gestureRecognizers].count);
            [self.view.window removeGestureRecognizer:sender];
        }
    }
}

这对于关闭单个模态视图非常有效。现在假设我有两个模态视图,一个从根视图控制器(视图 A)中调用,然后从第一个模态视图(视图 B)中调用另一个模态视图

有点像这样:

根视图 -> 视图 A -> 视图 B

当我点击关闭视图 B 时,一切正常。但是,当我尝试关闭视图 A 时,我收到 EXC_BAD_ACCESS 错误。打开僵尸后,似乎视图 B 仍然收到发送给它的消息 handleTapBehind:,即使它在视图 B 之后已被关闭并且内存不足已关闭。

我的问题是为什么视图 B 仍然收到消息? (handleTapBehind: 确保手势识别器应该已从关联窗口中删除。)在视图 B 已关闭后,如何将其发送到视图 A。

PS。上面的代码出现在 View A 和 View B 的控制器内部,并且是相同的。

编辑

以下是我如何调用模态视图控制器,此代码位于标准视图层次结构中的视图控制器内。

LBModalViewController *vc = [[LBModalViewController alloc] initWithNibName:@"LBModalViewController" bundle:nil];
[vc.myTableView setDataSource:vc];
[vc setDataArray:self.object.membersArray];

[vc setModalPresentationStyle:UIModalPresentationFormSheet];
[vc setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];

[vc.view setClipsToBounds:NO];

[self presentViewController:vc animated:YES completion:nil];

// This is a hack to modify the size of the presented view controller
CGPoint modalOrigin = vc.view.superview.bounds.origin;
[[vc.view superview] setBounds:CGRectMake(modalOrigin.x, modalOrigin.y, 425, 351)];
[vc.view setBounds:CGRectMake(modalOrigin.x, modalOrigin.y, 425, 351)];

差不多就是这样,其他的都很标准。

【问题讨论】:

  • 我刚刚将您的代码粘贴到一个打开和关闭 ARC 的新项目中,并且它可以正常工作而不会崩溃。还有什么可以引用视图 B 的吗?
  • 崩溃与 handleTapBehind 被发送到已关闭的视图有关。除了点击手势之外,没有其他任何东西将该选择器设置为目标。我的怀疑是我有两个相互叠加的轻击手势,单击一下就会触发它们。我试图循环浏览它们的数组并禁用除我想要使用的之外的所有内容,但这没有用。
  • 这真的很奇怪。异常的完整信息是什么?从表面上看,它仍然感觉像一个委托变量或其他东西引用了被解雇的视图,但显然你知道你的代码而我不知道。如果您能想到其他任何事情或想发布更多代码,我很乐意再考虑一下。
  • @JoshHudnall 感谢您提供帮助!我发布了一些附加代码,用于将模态视图带到屏幕上。如果我想到其他内容,我会发布更多内容。

标签: ios cocoa-touch ios5 uigesturerecognizer modalviewcontroller


【解决方案1】:
[self dismissModalViewControllerAnimated:YES];

[self.view.window removeGestureRecognizer:sender];

应该是:

[self.view.window removeGestureRecognizer:sender];

[self dismissModalViewControllerAnimated:YES];

否则你会得到不确定的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2011-03-14
    • 2012-05-14
    • 2023-03-04
    相关资源
    最近更新 更多