despedirModalViewControllerAnimado en desuso

Acabo de actualizar a XCode 4.5 para actualizar mi aplicación iOS para que se ejecute en la pantalla de 4 pulgadas para el iPhone 5, pero aparece un error de compilación.dismissModalViewControllerAnimated:' is deprecated en la línea:

[self dismissModalViewControllerAnimated:NO];

He intentado actualizar a la sobrecarga recomendada con un controlador de finalización (pero establecido en NULL) como este:

[self dismissModalViewControllerAnimated:NO completion:NULL];

Pero entonces esta línea arroja dos errores:

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

¡Gracias!

Respuestas a la pregunta(6)

Aquí está la versión correspondiente de presentViewController que usé si ayuda a otros novatos como yo:

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

Usé un ViewController 'genéricamente' y pude hacer que la vista modal apareciera de manera diferente dependiendo de lo que estaba llamado a hacer (usando setHidden y setImage). y las cosas funcionaban bien antes, pero performSelector ignora el 'conjunto' de cosas, por lo que al final parece ser una mala solución si tratas de ser eficiente como intenté ser ...

[self dismissModalViewControllerAnimated:NO]; ha sido desaprobado.

Utilizar[self dismissViewControllerAnimated:NO completion:nil]; en lugar.

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

En lugar de:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES];

... Y puedes usar:

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

En lugar de

[self presentModalViewController:picker animated:YES];    

Utilizar

[self dismissViewControllerAnimated:NO completion:nil];
Solución de preguntas

El nuevo método es:

[self dismissViewControllerAnimated:NO completion:nil];

La palabramodal ha sido removido; Como ha sido para la presentación de la convocatoria API:

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

Las razones fueron discutidas en el2012 WWDC Session 236 - La evolución de los controladores de vista en iOS Vídeo. Esencialmente, los controladores de vista presentados por esta API ya no son siempre modales, y como fueron agregando un controlador de finalización, fue un buen momento para cambiar el nombre.

En respuesta al comentario de Marc:

¿Cuál es la mejor manera de soportar todos los dispositivos 4.3 y superiores? El nuevo método no funciona en iOS4, pero el método anterior está obsoleto en iOS6.

Me doy cuenta de que esta es una pregunta casi por separado, pero creo que vale la pena mencionarla, ya que no todos tienen el dinero para actualizar todos sus dispositivos cada 3 años, así que muchos de nosotros tenemos algunos dispositivos más antiguos (antes de 5.0). Aún así, por más que me duela decirlo, debe considerar si vale la pena apuntar a menos de 5.0. Hay muchas API nuevas y geniales que no están disponibles debajo de 5.0. Y Apple continuamente hace que sea más difícil apuntarlos; El soporte de armv6 se elimina de Xcode 4.5, por ejemplo.

Para apuntar por debajo de 5.0 (siempre que el bloque de finalización sea nulo) simplemente use el comandorespondsToSelector: metodo

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

En respuesta a otro comentario de Marc:

¡Eso podría ser una gran cantidad de declaraciones If en mi aplicación! ... Estaba pensando en crear una categoría que encapsulara este código, ¿la creación de una categoría en UIViewControler me rechazaría?

y uno de Full Decent:

... ¿hay una manera de hacer que manualmente no presente una advertencia del compilador?

En primer lugar, no, creando una categoría enUIViewController en sí mismo no conseguirá que su aplicación sea rechazada; a menos que ese método de categoría se llame APIs privadas o algo similar.

Un método de categoría es un lugar extremadamente bueno para dicho código. Además, dado que solo habría una llamada a la API en desuso, solo habría una advertencia del compilador.

Para abordar el comentario (pregunta) de Full Decent, sí, puede suprimir las advertencias del compilador manualmente.Aquí hay un enlace a una respuesta en SO sobre ese tema. Un método de categoría también es un buen lugar para suprimir una advertencia del compilador, ya que solo está suprimiendo la advertencia en un solo lugar. Ciertamente no querrás ir silenciando el compilador de ninguna manera.

Si tuviera que escribir un método de categoría simple para esto, podría ser algo como esto:

@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 Generalmente solo puedes usar[self dismiss… y se reenviará automáticamente a lapresentingViewController. La excepción es si tiene varios controladores de vista presentados (en la forma anteriormente conocida como modal); Si este es el caso, tu objetivo es eldismiss… llame al controlador de vista cuya vista desea que permanezca después del despido, todas las vistas anteriores se descartarán a la vez.
 Jason McCreary04 sept. 2013 17:41
¿Debería cambiar el receptor dependiendo de dónde se llame? Es decir, podrías usarpresentingViewController?
 Marc26 sept. 2012 10:44
Gracias. ¡Eso podría ser un montón de declaraciones If en mi aplicación! Supongo que el mismo enfoque podría funcionar cuando se usa la propiedad 'modalViewController'. Estaba pensando en crear una categoría que encapsulara este código, ¿la creación de una categoría en UIViewControler me rechazaría?
 NJones26 sept. 2012 01:14
@Marc Agregué a mi respuesta para abordar su preocupación.
 NJones22 may. 2013 16:08
@FullDecent Sí puedes. Edité mi respuesta con algo de información sobre eso.
 William Entriken21 may. 2013 00:11
Para el codigoif ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){ [self presentViewController:test animated:YES completion:nil]; } else { [self presentModalViewController:test animated:YES]; } ¿hay una manera de hacer que manualmente no presente una advertencia del compilador?
 Marc24 sept. 2012 18:30
¿Cuál es la mejor manera de soportar todos los dispositivos 4.3 y superiores? El nuevo método no funciona en iOS4, pero el método anterior está obsoleto en iOS6. ¿Sitio de rock duro?

como este:

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

Beneficia a personas con TOC como yo;)

 Jsdodgers28 jul. 2013 00:25
Debería cambiar la instrucción if porque creo que un método en desuso no causarárespondsToSelector para devolver falso. Así, la nuevadismissViewControllerAnimated: nunca se llamará hasta una futura actualización donde posiblemente se puedan eliminardismissModalViewControllerAnimated: en total.

Su respuesta a la pregunta