dismissModalViewControllerAnimated已弃用

时间:2012-09-16 07:38:27

标签: ios ios6

我刚刚升级到XCode 4.5以更新我的iOS应用程序,以便在iPhone 5的4英寸显示屏上运行,但是我收到一条构建错误,上面写着dismissModalViewControllerAnimated:' is deprecated

[self dismissModalViewControllerAnimated:NO];

我尝试使用完成处理程序(但设置为NULL)更新为推荐的重载,如下所示:

[self dismissModalViewControllerAnimated:NO completion:NULL];

但是这一行引发了两个错误:

warning: 'TabBarController' may not respond to '-presentModalViewController:animated:completion:'
Instance method '-presentModalViewController:animated:completion:' not found (return type defaults to 'id')

谢谢!

6 个答案:

答案 0 :(得分:304)

新方法是:

[self dismissViewControllerAnimated:NO completion:nil];

模态一词已被删除;正如演示API调用一样:

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

原因在 2012 WWDC Session 236 - iOS上视图控制器的演变视频中进行了讨论。从本质上讲,这个API提供的视图控制器不再是模态的,因为它们正在添加一个完成处理程序,所以现在是重命名它的好时机。

回应Marc的评论:

  

支持所有4.3及以上设备的最佳方法是什么?新的   方法在iOS4中不起作用,但在iOS6中不推荐使用旧方法。

我意识到这几乎是一个单独的问题,但我认为值得一提,因为不是每个人都有钱每3年升级一次所有设备,所以我们很多人都有一些旧的(5.0之前的)设备。尽管如此,我还是很难说,你需要考虑是否值得将目标定在5.0以下。 5.0以下没有许多新的和酷的API。苹果公司不断努力瞄准它们;例如,从Xcode 4.5中删除了armv6支持。

要定位到5.0以下(只要完成块为零),只需使用方便的respondsToSelector:方法。

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [self presentViewController:test animated:YES completion:nil];
} else {
    [self presentModalViewController:test animated:YES];
}

回应Marc的另一条评论:

  

在我的应用程序中可能有很多If语句!...我是   考虑创建一个封装此代码的类别,会   在UIViewControler上创建一个类别让我被拒绝了吗?

和一个来自Full Decent:

  

...有没有办法手动导致它不呈现编译器警告?

首先,不,在UIViewController上创建一个类别本身不会让您的应用被拒绝;除非该类别方法称为私有API或类似的东西。

类别方法对于此类代码来说是一个非常好的地方。此外,由于只有一次调用已弃用的API,因此只会有一个编译器警告。

要解决Full Decent的评论(问题),是的,您可以手动抑制编译器警告。 Here is a link to an answer on SO on that very subject。类别方法也是抑制编译器警告的好地方,因为您只是在一个地方抑制警告。你肯定不想无缘无故地绕过编译器。

如果我要为此编写一个简单的类别方法,它可能是这样的:

@implementation UIViewController (NJ_ModalPresentation)
-(void)nj_presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion{
    NSAssert(completion == nil, @"You called %@ with a non-nil completion. Don't do that!",NSStringFromSelector(_cmd));
    if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
        [self presentViewController:viewControllerToPresent animated:flag completion:completion];
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        [self presentModalViewController:viewControllerToPresent animated:flag];
#pragma clang diagnostic pop
    }
}
@end

答案 1 :(得分:6)

现在在iOS 6及更高版本中,您可以使用:

[[Picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];

而不是:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

......你可以使用:

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

而不是

[self presentModalViewController:picker animated:YES];    

答案 2 :(得分:4)

[self dismissModalViewControllerAnimated:NO];已被弃用。

改为使用[self dismissViewControllerAnimated:NO completion:nil];

答案 3 :(得分:4)

使用

[self dismissViewControllerAnimated:NO completion:nil];

答案 4 :(得分:3)

警告仍然存在。为了摆脱它,我把它放到这样的选择器中:

if ([self respondsToSelector:@selector(dismissModalViewControllerAnimated:)]) {
    [self performSelector:@selector(dismissModalViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES]];
} else {
    [self dismissViewControllerAnimated:YES completion:nil];
}

像我一样对强迫症患者有益;)

答案 5 :(得分:0)

这是我使用的相应presentViewController版本,如果它可以帮助像我这样的其他新手:

if ([self respondsToSelector:@selector(presentModalViewController:animated:)]) {
    [self performSelector:@selector(presentModalViewController:animated:) withObject:testView afterDelay:0];
} else {
    [self presentViewController:configView animated:YES completion:nil];
}
[testView.testFrame setImage:info]; //this doesn't work for performSelector
[testView.testText setHidden:YES];

我曾经使用了一个ViewController'并且能够让模态视图以不同的方式显示(取决于它的调用)(使用setHidden和setImage)。并且事情之前工作得很好,但是performSelector忽略了'set'的东西,所以最后它似乎是一个糟糕的解决方案,如果你试图像我试图的那样高效...