多个模态视图点按即可关闭

时间:2012-06-17 09:44:35

标签: ios cocoa-touch ios5 uigesturerecognizer modalviewcontroller

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

- (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

当我点击取消View B时,一切都很顺利。但是当我尝试关闭View A时出现EXC_BAD_ACCESS错误。打开僵尸之后,看起来View B仍然收到了发送给它的消息handleTapBehind:,即使它被解雇并且已经被删除View B关闭后的内存。

我的问题是为什么View 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)];

这就是它,其他一切都很标准。

1 个答案:

答案 0 :(得分:2)

[self dismissModalViewControllerAnimated:YES];

[self.view.window removeGestureRecognizer:sender];

应该是:

[self.view.window removeGestureRecognizer:sender];

[self dismissModalViewControllerAnimated:YES];

否则你会得到未定义的结果。