dismissModalViewControllerAnimated弃用

我刚刚升级到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') 

谢谢!

新方法是:

 [self dismissViewControllerAnimated:NO completion:nil]; 

模态这个词已被删除; 因为它已经提供了API调用:

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

原因在2012年WWDC会议236 – iOSvideo视图控制器的发展中进行了讨论。 从本质上说,这个API提供的视图控制器不再总是模态的,而且由于它们正在添加一个完成处理程序,现在是重新命名它的好时机。

回应Marc的评论:

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

我意识到这几乎是一个单独的问题,但我认为值得一提,因为不是每个人都有钱每3年升级所有设备,所以我们很多人都有一些旧的(5.0之前的)设备。 尽pipe如此,尽pipe我很难说,但你需要考虑是否值得在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]; } 

针对Marc的另一个评论:

这可能是相当多的If语句在我的应用程序!…我正在考虑创build一个封装了这个代码的类别,将在UIViewControler上创build一个类别让我拒绝?

和一个来自全面体面:

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

首先,不,在UIViewController中创build一个类别本身不会让你的应用程序被拒绝; 除非该类别的方法称为私人API或类似的东西。

类别的方法是这样的代码非常好的地方。 而且,由于只有一个调用API,所以只会有一个编译器警告。

为了解决完全体面的评论(问题),是的,你可以手动压制编译器警告。 在这个主题上,有一个关于SO的答案 。 类别方法也是抑制编译器警告的好地方,因为你只是在一个地方抑制警告。 你当然不想绕着编译器无声地沉默。

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

 @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 

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

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

代替:

 [[Picker parentViewControl] dismissModalViewControllerAnimated:YES]; 

…你可以使用:

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

代替

 [self presentModalViewController:picker animated:YES]; 

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

使用[self dismissViewControllerAnimated:NO completion:nil]; 代替。

使用

 [self dismissViewControllerAnimated:NO completion:nil]; 

警告仍然存在。 为了摆脱它,我把它放到这样一个select器:

 if ([self respondsToSelector:@selector(dismissModalViewControllerAnimated:)]) { [self performSelector:@selector(dismissModalViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES]]; } else { [self dismissViewControllerAnimated:YES 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]; 

我一般使用了ViewController,并且能够使模态View看起来有所不同,取决于它被调用的方式(使用setHidden和setImage)。 而事情以前很好,但performSelector忽略“设置”的东西,所以最终似乎是一个糟糕的解决scheme,如果你试图有效率,我试图成为… …