web-dev-qa-db-ja.com

dismissModalViewControllerAnimatedは非推奨です

Xcode 4.5にアップグレードしてiOSアプリをiPhone 5の4インチディスプレイで実行するように更新しましたが、次の行でdismissModalViewControllerAnimated:' is deprecatedというビルドエラーが表示されます。

[self dismissModalViewControllerAnimated:NO];

次のように、完了ハンドラー(ただし、NULLに設定)を使用して、推奨されるオーバーロードに更新しようとしました。

[self dismissModalViewControllerAnimated:NO completion:NULL];

ただし、この行では2つのエラーがスローされます。

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

ありがとう!

100
Mick Byrne

新しい方法は次のとおりです。

[self dismissViewControllerAnimated:NO completion:nil];

Wordmodalは削除されました。提示するAPIコールの場合:

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

その理由については、2012 WWDC Session 236-The Evolution of View Controllers on iOSVideoで説明しました。基本的に、このAPIによって提供されるView Controllerは常にモーダルであるとは限りません。また、完了ハンドラーを追加していたため、名前を変更する良い機会でした。

Marcからのコメントに対する回答:

4.3以降のすべてのデバイスをサポートする最良の方法は何ですか?新しいメソッドはiOS4では機能しませんが、古いメソッドはiOS6では非推奨です。

これはほとんど別の質問であることを認識していますが、3年ごとにすべてのデバイスをアップグレードするお金がない人もいるので、言及する価値があると思います。それでも、それを言うのは苦痛ですが、5.0未満をターゲットにする価値があるかどうかを検討する必要があります。 5.0より下では利用できない多くの新しいAPIがあります。また、Appleは、ターゲットを絞ることを常に難しくしています。たとえば、armv6サポートはXcode 4.5から削除されました。

5.0未満をターゲットにするには(完了ブロックがnilである限り)、便利なrespondsToSelector:メソッドを使用します。

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

Marcからの別のコメントへの応答:

それは私のアプリケーションのかなり多くのIfステートメントになる可能性があります!...このコードをカプセル化するカテゴリを作成することを考えていましたが、UIViewControlerでカテゴリを作成すると拒否されますか?

フルディセントからの1つ:

...手動でコンパイラ警告を表示しないようにする方法はありますか?

まず、いいえ、UIViewControllerにカテゴリを作成するだけでは、アプリが拒否されません。そのカテゴリメソッドがプライベートAPIまたは類似のものを呼び出す場合を除きます。

カテゴリメソッドは、このようなコードに非常に適した場所です。また、廃止されたAPIの呼び出しは1つだけなので、コンパイラーの警告は1つしかありません。

Full Decentのコメント(質問)に対処するために、はい、手動でコンパイラの警告を抑制することができます。 これはまさにその主題に関するSOに関する回答へのリンクです 。カテゴリメソッドは、警告を1か所で抑制しているだけなので、コンパイラの警告を抑制するのに最適な場所でもあります。コンパイラーを無言で黙らせたくないのは確かです。

このために簡単なカテゴリメソッドを記述する場合、次のようなものになるでしょう。

@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
304
NJones

IOS 6以降では、次を使用できます。

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

の代わりに:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

...そして使用できます:

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

の代わりに

[self presentModalViewController:picker animated:YES];    
6
Dipang

[self dismissModalViewControllerAnimated:NO];は廃止されました。

代わりに[self dismissViewControllerAnimated:NO completion:nil];を使用してください。

4

つかいます

[self dismissViewControllerAnimated:NO completion:nil];
4
Mak083

警告はまだあります。それを取り除くために、私はそれをこのようなセレクターに入れました:

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

それは私のようなOCDを持つ人々に利益をもたらします;)

3
kjoelbro

私のような他の初心者に役立つ場合、私が使用した対応する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は「セット」のものを無視しますので、最終的には私がしようとしたように効率的にしようとすると貧しい解決策のようです...

0
Walter