dismissModalViewControllerAnimated弃用

问题描述:

我刚刚升级到4.5的XCode更新我的iOS应用到4英寸显示屏的iPhone 5上运行,但我发现了一个构建错误说就行了dismissModalViewControllerAnimated:' is deprecateddismissModalViewControllerAnimated弃用

[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') 

谢谢!

新方法是:

[self dismissViewControllerAnimated:NO completion:nil]; 

模态已被移除;由于它一直是呈现API调用: - 视图控制器的iOS上视频的演变

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

的原因是在2012 WWDC会议讨论236。从本质上讲,这个API提供的视图控制器不再总是模态的,并且由于它们添加了完成处理程序,现在是重新命名它的好时机。

在回答马克评论:

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

我知道这几乎是一个单独的问题,但我认为这是值得一提,因为不是每个人都有的钱升级所有设备,每3年这么多,我们有一些较早(5.0)设备。尽管如此,尽管我很难说,但你需要考虑它是否值得定位在5.0以下。有许多新的和酷的API在5.0以下不可用。而苹果正在不断加大瞄准它们的难度。例如,armv6支持从Xcode 4.5中删除。

要定位到低于5.0(只要完成块为零),请使用方便的respondsToSelector:方法。

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

在回答另一个马克评论:

这可能是相当多的if语句在我的应用程序......我创建封装该代码类别的 思维, 在UIViewControler上创建一个类别让我拒绝?

,一个来自完全体面:

...有没有办法手动会导致不提出一个编译器警告?

首先,不,创建一个类别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 
+2

支持所有4.3以上设备的最佳方式是什么?新方法在iOS4中不起作用,但旧方法在iOS6中不推荐使用。摇滚和艰难的地方? – Marc

+0

@Marc我加入到我的答案来解决您的问题。 – NJones

+0

谢谢。这可能是我的应用程序中的很多If语句!我想在使用'modalViewController'属性时可以使用相同的方法。 我正在考虑创建一个封装了这段代码的类,在UIViewControler上创建一个类别让我被拒绝? – Marc

现在的iOS 6及以上,你可以使用:

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

相反的:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES]; 

...你可以使用:

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

而不是

[self presentModalViewController:picker animated:YES];  

警告仍然存在。为了摆脱它,我把它变成像这样的选择:

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

它有利于人们像我这样的OCD)

+0

您应该切换if语句,因为我相信不推荐使用的方法不会导致'respondsToSelector'返回false。因此,新的'dismissViewControllerAnimated:'将永远不会被调用,直到将来可能会删除'dismissModalViewControllerAnimated:'完成。 – Jsdodgers

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

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

以下是相应的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]; 

我用了一个视图控制器“一般”和能够得到的模态视图显示不同,具体取决于什么被调用来做(使用setHidden和setImage)。并且事很好的工作之前,但performSelector忽略“设置”的东西,所以最后它似乎是一个贫穷的解决方案,如果您尝试是有效像我试图将...

使用

[self dismissViewControllerAnimated:NO completion:nil];