Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
211 views
in Technique[技术] by (71.8m points)

ios - dismissModalViewControllerAnimated deprecated

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 deprecated on the line:

[self dismissModalViewControllerAnimated:NO];

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

[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!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The new method is:

[self dismissViewControllerAnimated:NO completion:nil];

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

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

The reasons were discussed in the 2012 WWDC Session 236 - The Evolution of View Controllers on iOS Video. 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.

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.

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.

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

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:

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?

and one from Full Decent:

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

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

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.

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.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...