2012-09-16 15 views
99

he actualizado a XCode 4.5 para actualizar mi aplicación iOS para funcionar en la pantalla de 4 pulgadas para el iPhone 5, pero estoy recibiendo un error de compilación diciendo dismissModalViewControllerAnimated:' is deprecated en la línea:dismissModalViewControllerAnimated obsoleto

[self dismissModalViewControllerAnimated:NO]; 

he intentado actualizar a la sobrecarga recomendado con un controlador de finalización (pero establece en NULL) de esta manera:

[self dismissModalViewControllerAnimated:NO completion:NULL]; 

pero entonces esta línea de tiros dos errores:

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

Gracias!

Respuesta

300

El nuevo método es:

[self dismissViewControllerAnimated:NO completion:nil]; 

La palabra modal se ha eliminado; Como lo ha sido para la llamada a la API de presentación:

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

Las razones fueron discutidos en la WWDC 2012 Sesión 236 - La evolución de los controladores de Vista en IOS vídeo. Básicamente, los controladores de vista presentados por esta API ya no son siempre modales, y dado que estaban agregando un controlador de finalización, era un buen momento para cambiarle el nombre.

En respuesta al comentario de Marc:

Cuál es la mejor manera de apoyar a todos los dispositivos 4.3 y anteriores? El nuevo método no funciona en iOS4, sin embargo, el método anterior está en desuso en iOS6.

que dan cuenta de que esto es casi una cuestión distinta, pero creo que es digno de mención ya que no todos tienen el dinero para actualizar todos sus dispositivos cada 3 años por lo que muchos de nosotros tenemos algunos dispositivos más antiguos (pre 5.0). Aún así, por mucho que me duela decirlo, debe considerar si vale la pena focalizar por debajo de 5.0. Hay muchas API nuevas y geniales que no están disponibles por debajo de 5.0. Y Apple continuamente hace más difícil apuntarlos; El soporte de armv6 se elimina de Xcode 4.5, por ejemplo.

Para segmentar por debajo de 5.0 (siempre que el bloque de finalización sea nulo) simplemente use el práctico método respondsToSelector :.

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 un buen montón de If en mi solicitud ... Me pensar en la creación de una categoría que encapsula el código, ¿ crearía una categoría en UIViewControler y me rechazaría?

y uno de Full decente:

... ¿hay una manera de provocar manualmente que no presentará una advertencia del compilador?

En primer lugar, no, la creación de una categoría en UIViewController en sí misma no hará que su aplicación sea rechazada; a menos que ese método de categoría llamara API privadas o algo similar.

Un método de categoría es un lugar excesivamente 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 de forma manual. Here is a link to an answer on SO on that very subject. Un método de categoría también es un gran lugar para suprimir una advertencia del compilador, ya que solo está suprimiendo la advertencia en un solo lugar. Ciertamente no querrás silenciar al compilador de cualquier manera.

Si tuviera que escribir un método 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 
+2

¿Cuál es la mejor manera de admitir todos los dispositivos 4.3 y superiores? El nuevo método no funciona en iOS4, sin embargo, el método anterior está en desuso en iOS6. ¿Sitio de rock duro? – Marc

+0

@Marc Agregué mi respuesta para abordar su preocupación. – NJones

+0

Gracias. ¡Eso podría ser un montón de declaraciones If en mi aplicación! Supongo que el mismo enfoque podría funcionar al usar la propiedad 'modalViewController'. Estaba pensando en crear una categoría que encapsulara este código, ¿crearía una categoría en UIViewControler para que me rechace? – Marc

6

Ahora en iOS 6 y superior, que puede utilizar:

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

En lugar de:

[[Picker parentViewControl] dismissModalViewControllerAnimated:YES]; 

... Y puede utilizar:

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

En lugar de

[self presentModalViewController:picker animated:YES];  
3

La advertencia sigue ahí. Con el fin de deshacerse de él lo puse en un selector de la siguiente manera:

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

Se beneficia a las personas con TOC como yo;)

+0

Debe cambiar la instrucción if porque creo que un método obsoleto no hará que 'respondsToSelector' devuelva false. Por lo tanto, el nuevo 'dismissViewControllerAnimated:' no se invocará hasta una actualización futura en la que posiblemente eliminen 'dismissModalViewControllerAnimated:' en conjunto. – Jsdodgers

4

[self dismissModalViewControllerAnimated:NO]; ya no se utiliza.

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

0

Aquí está la versión presentViewController correspondiente que he utilizado 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]; 

que habían utilizado un ViewController 'genérica' y fue capaz de conseguir el modal Ver a aparecer de forma diferente dependiendo de lo que se fue llamado a hacer (usando setHidden y setImage). y las cosas funcionaban muy bien antes, pero ignora performSelector 'set' cosas, así que al final parece ser una mala solución si intenta ser eficiente como he tratado de ser ...

4

Uso

[self dismissViewControllerAnimated:NO completion:nil];