Estoy escribiendo una aplicación y necesito cambiar la vista si el usuario está mirando la aplicación mientras habla por teléfono.
He implementado el siguiente método:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
Pero no se llama cuando la aplicación vuelve al primer plano.
Sé que puedo implementar:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
Pero no quiero hacer esto. Prefiero poner toda mi información de diseño en el método viewWillAppear: y dejar que maneje todos los escenarios posibles.
Incluso he intentado llamar a viewWillAppear: desde applicationWillEnterForeground :, pero parece que no puedo determinar cuál es el controlador de vista actual en ese punto.
¿Alguien sabe la forma correcta de lidiar con esto? Estoy seguro de que me falta una solución obvia.
ios
objective-c
iphone
viewwillappear
Philip Walton
fuente
fuente
applicationWillEnterForeground:
para determinar cuándo su aplicación ha vuelto a ingresar al estado activo.isMemberOfClass
oisKindOfClass
, según sus necesidades.Respuestas:
El método
viewWillAppear
debe tomarse en el contexto de lo que está sucediendo en su propia aplicación, y no en el contexto de que su aplicación se coloque en primer plano cuando vuelva a cambiarla desde otra aplicación.En otras palabras, si alguien mira otra aplicación o atiende una llamada telefónica, luego vuelve a su aplicación que estaba en segundo plano, su UIViewController que ya estaba visible cuando dejó su aplicación 'no le importa', por así decirlo: en lo que a él respecta, nunca ha desaparecido y sigue siendo visible, y por eso
viewWillAppear
no se llama.Recomiendo no llamar a
viewWillAppear
ti mismo, ¡tiene un significado específico que no debes subvertir! Una refactorización que puede hacer para lograr el mismo efecto podría ser la siguiente:Entonces también se activa
doMyLayoutStuff
desde la notificación correspondiente:Por cierto, no hay una forma innovadora de saber cuál es el UIViewController 'actual'. Pero puede encontrar formas de evitarlo, por ejemplo, existen métodos delegados de UINavigationController para averiguar cuándo se presenta un UIViewController. Podría usar tal cosa para rastrear el último UIViewController que se ha presentado.
Actualizar
Si diseña interfaces de usuario con las máscaras de tamaño automático adecuadas en los diversos bits, a veces ni siquiera necesita lidiar con el diseño 'manual' de su interfaz de usuario; simplemente se trata ...
fuente
self.navigationController.topViewController
efectivamente lo proporciona, o al menos el que está en la parte superior de la pila, que sería el uno actual si este código se está activando en el hilo principal en un controlador de vista. (Podría estar equivocado, no he jugado mucho con él, pero parece funcionar.)appDelegate.rootViewController
funcionará también, pero podría devolver unUINavigationController
, y luego necesitará.topViewController
como dice @MatthewFrederick.Rápido
Respuesta corta
Use un
NotificationCenter
observador en lugar deviewWillAppear
.Respuesta larga
Para saber cuándo una aplicación vuelve del fondo, use un
NotificationCenter
observador en lugar deviewWillAppear
. Aquí hay un proyecto de muestra que muestra qué eventos ocurren cuando. (Esta es una adaptación de esta respuesta del Objetivo C ).Al iniciar la aplicación por primera vez, el orden de salida es:
Después de presionar el botón de inicio y luego volver a poner la aplicación en primer plano, el orden de salida es:
Entonces, si originalmente estaba tratando de usar,
viewWillAppear
entoncesUIApplication.willEnterForegroundNotification
probablemente sea lo que desea.Nota
A partir de iOS 9 y versiones posteriores, no es necesario eliminar el observador. La documentación dice:
fuente
Use el Centro de notificaciones en el
viewDidLoad:
método de su ViewController para llamar a un método y desde allí haga lo que se suponía que debía hacer en suviewWillAppear:
método. LlamarviewWillAppear:
directamente no es una buena opción.fuente
dealloc
método entonces.viewWillAppear:animated:
, uno de los métodos más confusos en los SDK de iOS en mi opinión, nunca se invoca en tal situación, es decir, el cambio de aplicación. Ese método solo se invoca de acuerdo con la relación entre la vista del controlador de vista y la ventana de la aplicación , es decir, el mensaje se envía a un controlador de vista solo si su vista aparece en la ventana de la aplicación, no en la pantalla.Cuando su aplicación pasa a segundo plano, obviamente, las vistas superiores de la ventana de la aplicación ya no son visibles para el usuario. En la perspectiva de la ventana de su aplicación, sin embargo, siguen siendo las vistas más altas y, por lo tanto, no desaparecieron de la ventana. Más bien, esas vistas desaparecieron porque la ventana de la aplicación desapareció. No desaparecieron porque desaparecieron de la ventana.
Por lo tanto, cuando el usuario vuelve a su aplicación, obviamente parece aparecer en la pantalla, porque la ventana aparece nuevamente. Pero desde la perspectiva de la ventana, no han desaparecido en absoluto. Por lo tanto, los controladores de vista nunca reciben el
viewWillAppear:animated
mensaje.fuente
Swift 4.2 / 5
fuente
Solo tratando de hacerlo lo más fácil posible, vea el código a continuación:
fuente