模态视图控制器无法自行解除

33

我在做什么:

在我的应用程序中,我使用以下代码呈现一个模态视图控制器(包含应用程序设置):

    optionsViewController.modalTransitionStyle = UIModalTransitionStylePartialCurl;
    [self presentModalViewController:optionsViewController animated:YES];
这个过渡效果将视图底部卷起来以显示一些设置选项(例如“Maps”应用程序)。当您点击页面顶部的原始视图仍然存在但变灰的区域时,模态视图控制器将自动关闭(由操作系统处理,我没有编写代码实现此功能)。
-
问题所在:
这在iOS 4中运行得很好(我的应用程序实际上已经在App Store上),但在iOS 5中,看起来苹果已经改变了这个转换的行为,视图控制器不再自动关闭。我正在尝试复制操作系统之前处理的行为,但无法弄清楚如何实现。
-
我尝试过的方法:
在选项视图顶部添加一个不可见按钮不起作用。那样页面就会完全卷起来,这不是我想要的。
除此之外,我卡住了。我该如何复制最初的工作方式(或者我一开始做错了吗!)。非常感谢任何帮助!

iOS 5受NDA保护,不能讨论。请记住它仍处于测试版阶段,因此在正式发布之前可能会发生变化。 - Nick Bull
@Nick 我明白。但是考虑到其他相同类型的转换在其他应用程序中似乎都能正常工作,我可能一直以来都在错误的方式下进行操作。 - Jordan Smith
这是在旧版iOS 5 beta上的一个问题,应该在5 beta 7上得到解决。 - aryaxt
@iradik 是的,那就是问题所在。在iOS 5的最终版本中似乎已经修复了这个问题。我接受了得票最多的答案,因为这个答案解决了与我的略有不同但相同的问题。这也是其他人会发现最有帮助的答案,因为另一个问题已经被苹果公司解决了。 - Jordan Smith
在iOS 5中它并不是固定的。只有当你点击视图的卷曲部分时,它才会关闭模态视图。否则,它将不会关闭。我不得不在底层视图上添加一个轻拍手势识别器来获得相同的行为。 - user468687
显示剩余4条评论
6个回答

71

兄弟,我遇到了同样的问题...这是我关于使用parentViewController找到的信息:

注意,在5.0之后,此方法将不再返回presenting view controller。

这在UIViewController的头文件中有说明...

我正在使用ShareKit,并且在iOS4中modalViewController工作得很好,但在iOS5中,它就无法自动关闭!这是因为他们的代码中,他们在使用:

    [[currentView parentViewController] dismissModalViewControllerAnimated:animated];

由于这是一个模态呈现的视图控制器,所以parentViewController将返回nil...

在寻找解决方案时,我发现了你的问题...因此,我决定自己修复它 :P

我将上一行更改为:

    [currentView dismissModalViewControllerAnimated:YES];

非常有效。


编辑: 根据对原始问题的理解不同,有两个答案。这是第二个答案:

在iOS5中,似乎模态控制器只有在单击翻页时才会关闭自身,而不是在翻页上方或背景处。为了实际上使模态视图在单击背景或翻页上方时关闭自身,我添加了以下代码到控制器中,以监听对模态视图的点击,但忽略对按钮的点击。这应该模仿之前版本的iOS中使用页面翻页的模态控制器时的行为。

- (void)viewDidLoad
{
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    tap.numberOfTapsRequired = 1;
    tap.numberOfTouchesRequired = 1;
    tap.delegate = self;          
    [backgroundView addGestureRecognizer:tap];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    //change it to your condition    
    if ([touch.view isKindOfClass:[UIButton class]]) {      
       return NO;
    }
    return YES;
}

- (void)handleTap:(UITapGestureRecognizer *)sender {
    [self dismissModalViewControllerAnimated:YES];
}

1
太棒了!这并不完全和我遇到的问题一样,但非常接近。我可以说行为上的新变化就是我正在面临的问题-所以应该能够从中找到解决方案。谢谢! - Jordan Smith
看起来我遇到的确切问题已经在最新的测试版中得到了解决 - 然而,这个问题很可能是由于这个原因造成的。这种微妙的差异很可能会导致其他iOS 5兼容性问题,所以请注意! - Jordan Smith
1
如何确保此代码向运行 iOS 4 的设备兼容? - jowie
1
希望我能在这个问题上提供不止一个点赞。很好——感谢您提供清晰的代码示例。我相信这节省了我很多时间。 - Danilo Campos
注意:在iOS 6中,dismissModalViewControllerAnimated:已被弃用。请改用dismissViewControllerAnimated:completion:。 - Matt Becker

15

你用来关闭模态视图控制器的代码是什么?我看到过像这样的代码:

[self.parentViewController dismissModalViewControllerAnimated: YES];

那种方法在一些版本的操作系统上无法工作,不过这个方法可以:

[self dismissModalViewControllerAnimated: YES];
应该。

2
在iOS 4中,我不需要做任何事情 - 操作系统会处理它。在iOS 5中,这似乎已经改变了(至少目前是这样)。上面的代码是我将要使用的,但我不知道如何在视图的顶半部分接收触摸(然后运行此代码)。查看“地图”应用程序以了解其工作原理。 - Jordan Smith
1
在iOS 6中,此方法已被弃用。请改用dismissViewControllerAnimated:completion - Dan Dyer

1

我曾经遇到过同样的问题,这也会影响那些使用:

 [self.parentViewController.parentViewController dismissModalViewControllerAnimated:YES];

我用观察者模式修复了它,在你的dismiss代码中添加了以下内容:

[[NSNotificationCenter defaultCenter] postNotificationName:@"yourObserverName" object:self];

还有在父级父级视图控制器中的以下代码:

// add in viewDidLoad for example
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissModalVCFromParent:) name:@"yourObserverName" object: nil];

//The function
- (void) dismissModalVCFromParent:(NSNotification *)notif
{
   [self dismissModalViewControllerAnimated:YES];
}

// Don't forget remove
[[NSNotificationCenter defaultCenter] removeObserver:self];

0
在iOS5中,模态控制器似乎只有在单击翻页卷曲区域时才会关闭自身,而不是在卷曲区域上方或背景上单击。 为了使模态视图在点击背景或卷曲区域上方时实际上能够关闭自身,我向控制器添加了以下代码,以便监听对模态视图的轻触,但忽略按钮的轻触。 这应该模拟在早期版本的 iOS 中使用带有页面翻页卷曲的模态控制器时的行为。
- (void)viewDidLoad
{
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    tap.numberOfTapsRequired = 1;
    tap.numberOfTouchesRequired = 1;
    tap.delegate = self;          
    [backgroundView addGestureRecognizer:tap];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    //change it to your condition    
    if ([touch.view isKindOfClass:[UIButton class]]) {      
       return NO;
    }
    return YES;
}

- (void)handleTap:(UITapGestureRecognizer *)sender {
    [self dismissModalViewControllerAnimated:YES];
}

0

这似乎在(现在的最终版本)iOS 5上运行正常。

我注意到你必须点击特定区域才能关闭页面翻页 - 在屏幕顶部边缘附近轻敲似乎没有任何作用,但是在页面翻页图形上方的中心模糊部分一直会导致关闭模态视图。

我不确定这种狭窄的轻敲区域行为是iOS 5新的还是已经存在而我以前从未注意过。希望这有所帮助!


0

谢谢大家,这节省了我很多时间。我刚刚注意到,根据UIViewControoler.h的源代码,presentModalViewControllerdismissModalViewController方法已经被弃用。现在有替代的presentViewControllerdismissViewController方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接