ios 不推荐使用dismissModalViewControllerAnimated

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12445190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:09:34  来源:igfitidea点击:

dismissModalViewControllerAnimated deprecated

iosios6

提问by Mick Byrne

I've just upgraded to XCode 4.5 to update my iOS app to run on the 4 inch display for the iPhone 5, but I'm getting a build error saying dismissModalViewControllerAnimated:' is deprecatedon the line:

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

[self dismissModalViewControllerAnimated:NO];

I've tried updating to the recommended overload with a completion handler (but set to NULL) like this:

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

[self dismissModalViewControllerAnimated:NO completion:NULL];

But then this line throws two errors:

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

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

Thanks!

谢谢!

回答by NJones

The new method is:

新方法是:

[self dismissViewControllerAnimated:NO completion:nil];

The word modalhas been removed; As it has been for the presenting API call:

模态一词已被删除;就像呈现 API 调用一样:

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

The reasons were discussed in the 2012 WWDC Session 236 - The Evolution of View Controllers on iOSVideo. Essentially, view controllers presented by this API are no longer always modal, and since they were adding a completion handler it was a good time to rename it.

原因在2012 WWDC Session 236 - The Evolution of View Controllers on iOSVideo 中讨论过。本质上,这个 API 呈现的视图控制器不再总是模态的,而且由于它们添加了一个完成处理程序,所以是重命名它的好时机。

In response to comment from Marc:

回应马克的评论:

What's the best way to support all devices 4.3 and above? The new method doesn't work in iOS4, yet the old method is deprecated in iOS6.

支持所有设备 4.3 及更高版本的最佳方式是什么?新方法在 iOS4 中不起作用,但旧方法在 iOS6 中已弃用。

I realize that this is almost a separate question, but I think it's worth a mention since not everyone has the money to upgrade all their devices every 3 years so many of us have some older (pre 5.0) devices. Still, as much as it pains me to say it, you need to consider if it is worth targeting below 5.0. There are many new and cool APIs not available below 5.0. And Apple is continually making it harder to target them; armv6 support is dropped from Xcode 4.5, for example.

我意识到这几乎是一个单独的问题,但我认为值得一提,因为不是每个人都有钱每 3 年升级一次他们的所有设备,所以我们中的许多人都有一些较旧的(5.0 之前的)设备。尽管如此,尽管我很难说出来,但您需要考虑是否值得将目标定位到 5.0 以下。有许多新的和酷的 API 在 5.0 以下不可用。苹果不断加大针对他们的难度;例如,从 Xcode 4.5 中删除了 armv6 支持。

To target below 5.0 (as long as the completion block is nil) just use the handy respondsToSelector: method.

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

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

In response to another comment from Marc:

回应 Marc 的另一条评论:

That could be quite a lot of If statements in my application!...I was thinking of creating a category that encapsulated this code, would creating a category on UIViewControler get me rejected?

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

and one from Full Decent:

一个来自 Full Decent:

...is there a way to manually cause that to not present a compiler warning?

...有没有办法手动使其不显示编译器警告?

Firstly, no, creating a category on UIViewControllerin and of itself will not get your app rejected; unless that category method called private APIs or something similar.

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

A category method is an exceedingly good place for such code. Also, since there would be only one call to the deprecated API, there would be only one compiler warning.

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

To address Full Decent's comment(question), yes you can suppress compiler warnings manually. Here is a link to an answer on SO on that very subject. A category method is also a great place to suppress a compiler warning, since you're only suppressing the warning in one place. You certainly don't want to go around silencing the compiler willy-nilly.

为了解决 Full Decent 的评论(问题),是的,您可以手动取消编译器警告。这是有关该主题的 SO 答案的链接。类别方法也是抑制编译器警告的好地方,因为您只是在一个地方抑制警告。您当然不想随意地使编译器静音。

If I was to write a simple category method for this it might be something like this:

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

@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

回答by Dipang

Now in iOS 6 and above, you can use:

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

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

Instead of:

代替:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

...And you can use:

...你可以使用:

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

Instead of

代替

[self presentModalViewController:picker animated:YES];    

回答by Jayprakash Dubey

[self dismissModalViewControllerAnimated:NO];has been deprecated.

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

Use [self dismissViewControllerAnimated:NO completion:nil];instead.

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

回答by Mak083

Use

[self dismissViewControllerAnimated:NO completion:nil];

回答by kjoelbro

The warning is still there. In order to get rid of it I put it into a selector like this:

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

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

It benefits people with OCD like myself ;)

它使像我这样的强迫症患者受益;)

回答by Walter

Here is the corresponding presentViewController version that I used if it helps other newbies like myself:

这是我使用的相应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];

I had used a ViewController 'generically' and was able to get the modal View to appear differently depending what it was called to do (using setHidden and setImage). and things were working nicely before, but performSelector ignores 'set' stuff, so in the end it seems to be a poor solution if you try to be efficient like I tried to be...

我已经“一般地”使用了一个 ViewController,并且能够根据调用它的功能(使用 setHidden 和 setImage)使模态视图显示不同。之前一切都很好,但是 performSelector 忽略了“设置”的东西,所以如果你像我试图那样努力提高效率,那么最终这似乎是一个糟糕的解决方案......