dismissModalViewControllerAnimated veraltet

Ich habe gerade ein Upgrade auf XCode 4.5 durchgeführt, um meine iOS-App für das 4-Zoll-Display des iPhone 5 zu aktualisieren, aber es wird eine Fehlermeldung angezeigtdismissModalViewControllerAnimated:' is deprecated an der Leitung:

[self dismissModalViewControllerAnimated:NO];

Ich habe versucht, mit einem Completion-Handler auf die empfohlene Überladung zu aktualisieren (aber auf NULL gesetzt):

[self dismissModalViewControllerAnimated:NO completion:NULL];

Aber dann wirft diese Zeile zwei Fehler:

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

Vielen Dank!

Antworten auf die Frage(6)

[self dismissModalViewControllerAnimated:NO]; wurde veraltet.

Benutzen[self dismissViewControllerAnimated:NO completion:nil]; stattdessen.

Benutzen

[self dismissViewControllerAnimated:NO completion:nil];
Lösung für das Problem

[self dismissViewControllerAnimated:NO completion:nil];

Das Wortmodal wurde entfernt; Wie schon für den präsentierenden API-Aufruf:

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

Die Gründe wurden in der2012 WWDC Session 236 - Die Evolution der View Controller unter iOS Video. Im Wesentlichen sind die von dieser API präsentierten Ansichtscontroller nicht mehr immer modal, und da sie einen Completion-Handler hinzugefügt haben, war es ein guter Zeitpunkt, ihn umzubenennen.

Auf Kommentar von Marc:

Was ist der beste Weg, um alle Geräte 4.3 und höher zu unterstützen? Die neue Methode funktioniert in iOS4 nicht, die alte Methode ist in iOS6 jedoch veraltet.

Mir ist klar, dass dies fast eine separate Frage ist, aber ich denke, dass es eine Erwähnung wert ist, da nicht jeder das Geld hat, alle drei Jahre alle seine Geräte zu aktualisieren, so dass viele von uns einige ältere (vor 5.0) Geräte haben. So sehr es mich auch schmerzt, es zu sagen, Sie müssen überlegen, ob es sich lohnt, ein Targeting unter 5,0 durchzuführen. Es gibt viele neue und coole APIs, die unter 5.0 nicht verfügbar sind. Und Apple macht es immer schwieriger, diese Ziele zu erreichen. Die Unterstützung für Armv6 entfällt beispielsweise von Xcode 4.5.

Um unter 5.0 zu zielen (solange der Completion Block Null ist), benutze einfach das HandyrespondsToSelector: Methode.

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

Als Antwort auf einen anderen Kommentar von Marc:

Das könnte eine Menge von If-Anweisungen in meiner Anwendung sein! ... Wenn ich darüber nachdachte, eine Kategorie zu erstellen, die diesen Code enthält, würde die Erstellung einer Kategorie in UIViewControler mich zurückweisen?

und einer von Full Decent:

... gibt es eine Möglichkeit, manuell zu veranlassen, dass keine Compiler-Warnung angezeigt wird?

Erstens, nein, erstellen Sie eine Kategorie aufUIViewController an und für sich wird Ihre App nicht abgelehnt; es sei denn, diese Kategoriemethode nennt sich private APIs oder ähnliches.

Eine Kategoriemethode ist ein überaus guter Ort für einen solchen Code. Da es nur einen Aufruf der veralteten API geben würde, gäbe es auch nur eine Compilerwarnung.

Um den Kommentar (die Frage) von Full Decent zu beantworten, können Sie Compiler-Warnungen manuell unterdrücken.Hier ist ein Link zu einer Antwort auf SO zu diesem Thema. Eine Kategoriemethode ist auch ein großartiger Ort, um eine Compiler-Warnung zu unterdrücken, da Sie die Warnung nur an einer Stelle unterdrücken. Sie wollen den Compiler nicht einfach so zum Schweigen bringen.

Wenn ich dafür eine einfache Kategoriemethode schreiben würde, könnte dies etwa so aussehen:

@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
 NJones22. Sept. 2013, 17:03
@JasonMcCreary Im Allgemeinen können Sie nur verwenden[self dismiss… und es wird automatisch an die weitergeleitetpresentingViewController. Die Ausnahme ist, wenn Sie mehrere Ansichtssteuerungen anzeigen lassen (früher als modal bezeichnet). Wenn dies der Fall ist, zielen Sie auf diedismiss… Rufen Sie den View Controller an, dessen View Sie nach der Entlassung behalten möchten. Alle oben genannten Views werden sofort entlassen.
 Jason McCreary04. Sept. 2013, 17:41
Sollte sich der Empfänger ändern, je nachdem wo dieser angerufen wird? Das heißt, könnten Sie verwendenpresentingViewController?
 NJones26. Sept. 2012, 01:14
@Marc Ich habe zu meiner Antwort hinzugefügt, um Ihr Anliegen anzusprechen.
 Marc26. Sept. 2012, 10:44
Vielen Dank. Das könnten ziemlich viele If-Aussagen in meiner Bewerbung sein! Ich denke, der gleiche Ansatz könnte funktionieren, wenn die 'modalViewController'-Eigenschaft verwendet wird. Ich habe darüber nachgedacht, eine Kategorie zu erstellen, die diesen Code enthält. Würde das Erstellen einer Kategorie in UIViewControler mich ablehnen?
 William Entriken21. Mai 2013, 00:11
Für den Codeif ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){ [self presentViewController:test animated:YES completion:nil]; } else { [self presentModalViewController:test animated:YES]; } Gibt es eine Möglichkeit, manuell zu veranlassen, dass keine Compiler-Warnung angezeigt wird?
 NJones22. Mai 2013, 16:08
@FullDecent Ja, das kannst du. Ich habe meine Antwort mit einigen Informationen dazu bearbeitet.
 Marc24. Sept. 2012, 18:30
Was ist der beste Weg, um alle Geräte 4.3 und höher zu unterstützen? Die neue Methode funktioniert in iOS4 nicht, die alte Methode ist in iOS6 jedoch veraltet. Rock und ein harter Ort?

Ab iOS 6 können Sie Folgendes verwenden:

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

Anstatt:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

... und Sie können verwenden:

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

Anstatt

[self presentModalViewController:picker animated:YES];    

die ich verwendet habe, wenn sie anderen Neulingen wie mir hilft:

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];

Ich hatte einen ViewController "generisch" verwendet und konnte die modale Ansicht je nach Aufruf (mit setHidden und setImage) unterschiedlich darstellen. und die Dinge funktionierten gut vorher, aber performSelector ignoriert 'set'-Sachen, so dass es am Ende eine schlechte Lösung zu sein scheint, wenn Sie versuchen, effizient zu sein, wie ich es versucht habe ...

lege ich es in einen Selektor wie diesen:

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

Es kommt Menschen mit Zwangsstörungen wie mir zugute;)

 Jsdodgers28. Juli 2013, 00:25
Sie sollten die if-Anweisung wechseln, da ich glaube, dass eine veraltete Methode nicht dazu führen wirdrespondsToSelector falsch zurückgeben. So ist das neuedismissViewControllerAnimated: wird erst bei einem zukünftigen Update aufgerufen, bei dem sie möglicherweise entfernendismissModalViewControllerAnimated: insgesamt.

Ihre Antwort auf die Frage