当前位置:  开发笔记 > 编程语言 > 正文

Iphone SDK通过点击它来解除ipad上的Modal ViewControllers

如何解决《IphoneSDK通过点击它来解除ipad上的ModalViewControllers》经验,为你挑选了6个好方法。

我想在用户点击模态视图时解雇FormSheetPresentation模式视图控制器...我已经看到一堆应用程序这样做(例如在ipad上的ebay)但我无法弄清楚如何从触摸中禁用底层视图当模态视图像这样显示时(他们是否可能将它呈现为一个弹出窗口?)......任何人都有任何建议吗?



1> Danilo Campo..:

我迟到了一年,但这很简单.

让您的模态视图控制器将手势识别器附加到视图的窗口:

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];
[recognizer release];

处理代码:

- (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]) 
        {
           // Remove the recognizer first so it's view.window is valid.
          [self.view.window removeGestureRecognizer:sender];
          [self dismissModalViewControllerAnimated:YES];
        }
     }
}

就是这样.HIG被诅咒,这是一种有用且常常是直观的行为.


1.当我在viewDidLoad中初始化gestureRecognizer时它不起作用,但是当我在viewDidAppear中初始化时它确实有效.
这已经停止在iOS8/XCode 6(4)上为我工作!!
将位置代码更改为:"CGPoint location = [tapSender locationInView:self.presentingViewController.view];"
测试将UITapGestureRecognizer初始化代码放在_viewDidAppear中:_
2. ModalViews通常有与之关联的代理.务必通知代表你被解雇了.此外,如果有任何其他方式解除模态视图,那么您需要一个集中的方法来删除手势识别器
请注意iOS 4和iOS 5之间的不兼容性; 在iOS 5中,必须在`viewDidAppear`中添加识别器,如上所述; 在iOS 4上,这不是必需的.还要注意`parentViewController`的行为[在iOS 5中更改](http://omegadelta.net/2011/11/04/oh-my-god-they-killed-parentviewcontroller/).

2> Jann..:

其他应用程序不使用模态视图,如果它们允许通过单击其外部来解除视图. UIModalPresentationFormSheets这种方式不能被解雇.(也不是,SDK3.2中的任何UIModal都可以).只需UIPopoverController点击该区域外即可解散.应用程序开发人员很可能(虽然针对Apple的iPad HIG)遮住了背景屏幕,然后显示UIPopoverController它看起来像UIModalPresentationFormSheets(或其他UIModal View).

[...] UIModalPresentationCurrentContext样式允许视图控制器采用其父级的表示样式.在每个模态视图中,灰色区域显示基础内容,但不允许在该内容中使用水龙头.因此,与弹出窗口不同,您的模态视图仍必须具有允许用户关闭模态视图的控件.

有关详细信息,请参阅开发人员站点上的iPad程序指南(页46 - "为模态视图配置演示样式")



3> Erich..:

对于iOS 8,您必须UIGestureRecognizer在横向方向上实现,并交换轻敲位置的(x,y)坐标.不确定这是否是由于iOS 8错误造成的.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // add gesture recognizer to window

    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];
    recognizer.delegate = self;
}

- (void)handleTapBehind:(UITapGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateEnded) {

        // passing nil gives us coordinates in the window
        CGPoint location = [sender locationInView:nil];

        // swap (x,y) on iOS 8 in landscape
        if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
            if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
                location = CGPointMake(location.y, location.x);
            }
        }

        // 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]) {

            // remove the recognizer first so it's view.window is valid
            [self.view.window removeGestureRecognizer:sender];
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }
}


#pragma mark - UIGestureRecognizer Delegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return YES;
}



4> 小智..:

上面的代码效果很好,但我会将if语句更改为,

    if (!([self.view pointInside:[self.view convertPoint:location fromView:self.view.window] withEvent:nil] || [self.navigationController.view pointInside:[self.navigationController.view convertPoint:location fromView:self.navigationController.view.window] withEvent:nil]))

    {
        // Remove the recognizer first so it's view.window is valid.
        [self.view.window removeGestureRecognizer:sender];
        [self dismissModalViewControllerAnimated:YES];
    }

这样可以确保您仍然可以与导航栏进行交互,否则点击它会解除模态视图.



5> Mazyod..:

为iOS 8更新了答案

显然,在iOS 8中,它UIDimmingView有一个轻敲手势识别器,它会干扰初始实现,因此我们忽略它并且不要求它失败.


这是速度的时代,所以大多数可能只是复制上面的代码.但是,不幸的是,当涉及到代码时,我遭受强迫症.

这是一个模块化解决方案,使用Danilo Campos的答案和类别.它还解决了一个重要的错误,如果你通过其他方式解雇你的模态,如上所述.

注意: if语句是因为我使用iPhone和iPad的视图控制器,只有iPad需要注册/取消注册.

更新:要点已更新,因为它无法正常使用令人敬畏的FCOverlay代码,并且它不允许在呈现的视图中识别手势.那些问题是固定的.使用该类别非常简单:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if (self.presentingViewController) {
        [self registerForDismissOnTapOutside];
    }
}

- (void)viewWillDisappear:(BOOL)animated
{
    if (self.presentingViewController) {
        [self unregisterForDismissOnTapOutside];
    }

    [super viewWillDisappear:animated];
}



6> Samidjo..:

将此代码复制粘贴到ModalViewController中:

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    //Code for dissmissing this viewController by clicking outside it
    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])
        {
            // Remove the recognizer first so it's view.window is valid.
            [self.view.window removeGestureRecognizer:sender];
            [self dismissModalViewControllerAnimated:YES];
        }
    }
}

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有