Afin de créer un UIView
au-dessus de toutes les vues comme le comportement de UIAlertView
, la meilleure façon que je vois est de le mettre dans la fenêtre de l'application, ce qui consiste à ajouter la vue à:
[[[UIApplication sharedApplication] delegate] window]
Cependant, l'inconvénient que j'ai trouvé est qu'il ne prend pas automatiquement en rotation. Pour qu'il prenne en rotation, la meilleure façon de faire est d'ajouter la vue sur AppDelegate actuel window.navigationController
/rootViewController
, cependant, ce faisant, il ne sera plus au-dessus de tout. Disons que lorsque la vue s'affiche et qu'il y a une fenêtre contextuelle modalViewController, la vue modale couvrira certainement la vue.
Ma question est, est-il possible d'ajouter une sous-vue à la fenêtre la plus haute et supporte l'orientation? Ai-je besoin de deux jeux de fichiers Nib dans ce cas? Comment UIAlertView
fait la magie pour combiner le support supérieur et d'orientation? Quand je regarde dans le UIAlertView.h
, Je vois qu'il y a en fait 2 UIWindows
, une fois s'appelle originalWindow
et une autre appelée dimWindow
. Y a-t-il un endroit où je peux trouver le code source de UIAlertView.m
?
La meilleure solution que j'ai trouvée consiste à créer une vue de conteneur transparente, à ajouter ce conteneur à la fenêtre et à placer votre alerte à l'intérieur du conteneur. Vous pouvez ensuite vous inscrire à UIApplicationWillChangeStatusBarOrientationNotification
pour recevoir des événements de rotation et transformer le conteneur; cela vous permet de manipuler indépendamment le cadre de l'alerte:
- (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);
}];
}
Vous pouvez, si vous le souhaitez, créer une fenêtre entièrement nouvelle avec sa propriété windowLevel
définie sur UIWindowLevelAlert
, ce qui garantira que la fenêtre restera au-dessus de toutes les autres vues, y compris le clavier, mais la gestion des fenêtres devient un peu délicat. La solution ci-dessus devrait suffire pour la plupart des besoins.
Le problème avec simplement l'ajout d'une vue d'un contrôleur de vue à une fenêtre est qu'il n'est pas garanti de recevoir toute la rotation et view[Will|Did][Disa|A]ppear:
messages sauf s'il est ajouté au contrôleur de vue hierarchy via addChildViewController:
sur le contrôleur de vue racine.
Seule la première sous-vue de UIWindow
est informée des changements d'orientation. (<iOS8)
Votre question est très similaire à celle-ci:
Plusieurs vues dans une fenêtre UIWindow
Comme le dit la réponse, vous pouvez vous inscrire aux notifications de changements d'orientation et gérer le relais de votre sous-vue `` en haut '' de cette façon.
Voici une solution possible, j'explique en quelques étapes.
UIViewController
au lieu de UIView
, Disons que la classe nommée TopViewController
héritée par UIViewController
TopViewController
héritée de UIViewController
possède des méthodes répondant à Afficher les événements de rotation. Les événements de rotation peuvent être capturés maintenant.Enfin, vous pouvez placer la vue TopViewController
en haut de UIWindow
en utilisant la même méthode que celle que vous avez mentionnée dans votre question.
[[[[UIApplication sharedApplication] delegate] window] addSubview:(TopViewController object).view];
J'espère que cela t'aides.