iphone - alertas - Vista sobre todo: subvista UIWindow subvista UIViewController
uialertcontroller ios (3)
Aquí hay una posible solución, estoy explicando en unos pocos pasos.
- Comience con una clase heredada
UIViewController
lugar deUIView
, Digamos una clase llamadaTopViewController
heredada porUIViewController
- Como no puede registrar la rotación de dispositivo / interfaz en la clase heredada UIView, la clase
TopViewController
que se hereda deUIViewController
tiene métodos que responden a Ver eventos de rotación. Los eventos de rotación se pueden capturar ahora. Por último, puede colocar la vista
TopViewController
en la parte superior deUIWindow
utilizando el mismo método que mencionó en su pregunta.[[[[UIApplication sharedApplication] delegate] window] addSubview:(TopViewController object).view];
Espero que esto ayude.
Para poder realizar una vista UIView
sobre todas las vistas, como el comportamiento de UIAlertView
, la mejor manera de verlo es colocarlo en la ventana de la aplicación, que es al agregar la vista a:
[[[UIApplication sharedApplication] delegate] window]
Sin embargo, el inconveniente que encontré es que no toma automáticamente la rotación. Para que window.navigationController
en rotación, la mejor manera de hacerlo es agregar la vista en la window.navigationController
actual de AppDelegate window.navigationController
/ rootViewController
, sin embargo, al hacer esto ya no estará por encima de todo. Digamos que cuando se muestra la vista y hay una ventana emergente modalViewController, la vista modal ciertamente cubrirá la vista.
Mi pregunta es, ¿es posible agregar una subvista a la ventana superior y la orientación de soporte? ¿Necesito dos conjuntos de archivos Nib en este caso? ¿Cómo hace UIAlertView
la magia para combinar la máxima compatibilidad con la orientación? Cuando miro en UIAlertView.h
, veo que en realidad hay 2 UIWindows
, una vez que se llama originalWindow
y otra llamada dimWindow
. ¿Hay algún lugar donde pueda encontrar el código fuente de UIAlertView.m
?
La mejor solución que he encontrado es crear una vista de contenedor transparente, agregar ese contenedor a la ventana y colocar su alerta dentro del contenedor. Luego, puede registrarse en UIApplicationWillChangeStatusBarOrientationNotification
para recibir eventos de rotación y transformar el contenedor; Esto le permite manipular de forma independiente el marco de la alerta:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
self.container = [[UIView alloc] initWithFrame:self.window.bounds];
[self.container addSubview:self.alertView];
[self.window addSubview:self.container];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(statusBarWillRotate:)
name:UIApplicationWillChangeStatusBarOrientationNotification
object:nil];
...
}
...
- (void)statusBarWillRotate:(NSNotification *)theNotification
{
CGFloat rotation = 0;
switch ([notification[UIApplicationStatusBarOrientationUserInfoKey] intValue])
{
case UIInterfaceOrientationLandscapeLeft:
rotation = -M_PI_2;
break;
case UIInterfaceOrientationLandscapeRight:
rotation = M_PI_2;
break;
case UIInterfaceOrientationPortraitUpsideDown:
rotation = M_PI;
break;
case UIInterfaceOrientationPortrait:
default:
rotation = 0;
break;
}
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(rotation);
CGSize rotatedSize = CGRectApplyAffineTransform(self.window.bounds, rotationTransform).size;
[UIView animationWithDuration:[UIApplication sharedApplication].statusBarOrientationAnimationDuration
animations:^{
self.container.transform = rotationTransform;
// Transform invalidates the frame, so use bounds/center
self.container.bounds = CGRectMake(0, 0, rotatedSize.width, rotatedSize.height);
self.container.center = CGPointMake(self.window.bounds.size.width / 2, self.window.bounds.size.height / 2);
}];
}
Si lo desea, puede crear una ventana completamente nueva con su propiedad windowLevel
establecida en UIWindowLevelAlert
, lo que garantizará que la ventana permanezca por encima de todas las demás vistas, incluido el teclado, pero la administración de ventanas se vuelve un poco complicada. La solución anterior debería ser suficiente para la mayoría de las necesidades.
El problema simplemente al agregar la vista de un controlador de vista a una ventana es que no se garantiza que reciba toda la rotación y los mensajes de view[Will|Did][Disa|A]ppear:
a menos que se agregue a la jerarquía del controlador de vista mediante addChildViewController:
en el controlador de vista raíz.
Solo la primera subvista de UIWindow
recibe información sobre los cambios de orientación. (<iOS8)
Tu pregunta es muy similar a esta:
Múltiples vistas en una ventana UI
Como dice la respuesta, puede registrarse para recibir notificaciones de cambios de orientación y manejar la retransmisión de su subvista ''en la parte superior'' de esa manera.