Personnalisé UIWindows ne tournent pas correctement dans iOS 8
Obtenir votre application en mode paysage et exécuter le code suivant:
UIWindow *toastWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
toastWindow.hidden = NO;
toastWindow.backgroundColor = [[UIColor cyanColor] colorWithAlphaComponent:0.5f];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[toastWindow removeFromSuperview];
});
Dans iOS 7, vous obtiendrez un bleu transparent overlay sur le dessus de la totalité de l'écran qui disparaît au bout de 5 secondes. Dans iOS 8, vous obtiendrez un bleu transparent overlay qui couvre un peu plus de la moitié de l'écran
De toute évidence, cela a quelque chose à voir avec le changement Apple dans iOS 8, où les coordonnées d'écran sont maintenant interface orientée au lieu de périphérique orienté, mais dans la vraie Pomme de mode, ils semblent avoir laissé une myriade de bugs dans le mode paysage et la rotation.
Je me permet de "corriger" cela en vérifiant si le dispositif d'orientation est paysage et de retourner la largeur et la hauteur de l'écran principal de limites, mais qui semble comme un horrible hack qui va briser quand Apple change tout nouveau dans iOS 9.
CGRect frame = [[UIScreen mainScreen] bounds];
if (UIInterfaceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
frame.size.width = frame.size.height;
frame.size.height = [[UIScreen mainScreen] bounds].size.width;
}
UIWindow *toastWindow = [[UIWindow alloc] initWithFrame:frame];
toastWindow.hidden = NO;
toastWindow.backgroundColor = [[UIColor cyanColor] colorWithAlphaComponent:0.5f];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[toastWindow removeFromSuperview];
});
Quelqu'un a été confronté à ce problème et de trouver une meilleure, moins cassants solution?
EDIT: je sais que je pourrais simplement utiliser une UIView et l'ajouter à la fenêtre clé mais je voudrais mettre quelque chose sur le dessus de la barre d'état.
Je ne vois rien dans votre code qui est fragile. De quoi parles-tu? Si votre plainte est qu'il n'y a pas de mise en page automatique pour windows... alors la réponse est d'utiliser des points de vue au lieu de windows. Simple.
C'est ce qu'Apple a dit à propos de windows: "la Plupart des applications iOS de créer et d'utiliser une seule fenêtre au cours de leur vie. [...] Toutefois, si l'application prend en charge l'utilisation d'un écran externe pour la vidéo, elle peut créer une nouvelle fenêtre pour afficher du contenu sur un écran externe. Toutes les autres fenêtres sont généralement créés par le système". En d'autres termes, si vous en sortez Apple a recommandé l'utilisation de windows, alors vous êtes sur votre propre et Apple ne va pas faire quelque chose pour le faire à l'aide de plusieurs fenêtres facile ni qu'ils s'excluent eux-mêmes des changements incompatibles.
Sérieusement, je suis avec Reid, où en êtes-vous de cette information?
UIWindowLevel
de l'empilement de niveau est disponible dans UIKit depuis iOS 2.0 et avec iOS 7, la raison de l'utilisation de cette API n'a jamais été mieux!En disant "la Plupart des applications iOS de créer et d'utiliser une seule fenêtre..." pas, une recommandation, un simple état de fait. les Applications iOS ont été en utilisant des Fenêtres multiples, pour un long temps, et Apple briser ce devrait être reconnue comme un échec de leur part, pas le nôtre.
OriginalL'auteur Reid Main | 2014-11-03
Vous devez vous connecter pour publier un commentaire.
Votre "réparer" n'est pas très grande pour une autre raison, en ce qu'elle ne fait pas tourner la fenêtre, de sorte que le texte et les autres sous-vues apparaissent avec l'orientation adéquate. En d'autres termes, si vous avez toujours voulu renforcer la fenêtre avec les autres sous-vues, ils seraient orientés de manière incorrecte.
...
Dans iOS8, vous devez définir la rootViewController de votre fenêtre, et que rootViewController besoin de retourner les valeurs appropriées de "shouldAutoRotate" et "supportedInterfaceOrientations'. Il y a un peu plus sur ce à: https://devforums.apple.com/message/1050398#1050398
Si vous n'avez pas de rootViewController de votre fenêtre, vous êtes effectivement dire que le cadre de la fenêtre ne doit jamais tourner automatiquement. Dans iOS7 n'en est pas de faire une différence, car le cadre n'était pas fait ce travail pour vous de toute façon. Dans iOS8, le cadre est de gérer les rotations, et il pense que c'est de faire ce que vous avez demandé (par le fait d'avoir un néant rootViewController) quand elle limite les limites de votre fenêtre.
Essayez ceci:
Maintenant, ajoutez rootViewController à la fenêtre de votre après il est instancié:
supportedInterfaceOrientations
retourneUIInterfaceOrientationMaskAll
. Vous avez raison cependant. J'ai juste besoin de créer un "dummy" UIViewController et tout est allé presque de retour à la façon dont elle a été dans iOS 7. Il existe une différence majeure: c'est votre UIWindow de limites doit correspondre au dispositif de limites alors qu'il n'en avait pas besoin que dans iOS 8.Bon conseil sur les limites, qui était pour moi. Merci.
L'ajout de
shouldRotate:
etsupportedInterfaceOrientations
à la rootViewController dans mon UIWindow sous-classe corrections question sur iOS 8. Merci beaucoup!Comment avez-vous obtenir le mannequin contrôleur de travailler? Pour moi, quand la mettre en Œuvre, les touches sont désactivées sur mon alerte. Est-il autre chose que vous avez à faire?
En regardant en arrière à mon code je n'ai rien fait de spécial. Juste créé un UIWindow, a ajouté un mannequin afficher le contrôleur de la vue racine contrôleur de gestion, puis ajouté à mon habitude UIView à la fenêtre. Je suppose que vous êtes en mesure de voir votre alerte et ne pas être en mesure d'agir sur elle?
OriginalL'auteur Rich Waters
Je crois que vous devez convertir la
UICoordinateSpace
.Sur l'iPhone 6 Plus d'apps peuvent désormais lancer déjà dans l'orientation paysage, ce qui a foiré une application que je suis en train de travailler sur le, car elle ne prend en charge l'orientation portrait à travers la plupart de l'application, à l'exception d'un seul écran (c'nécessaires à l'appui de paysage dans le plist).
Le code qui fixe cela a été comme suit:
et calculer les limites avec le code suivant:
J'espère que cela va vous conduire dans la bonne direction.
Oui, si vous définissez un rootViewController sur le UIWindow vous pouvez contrôler les orientations à travers les méthodes habituelles sur UIViewController.
Alors que cela fonctionne, je ne suis pas encore sûr à 100% c'est ce qu'Apple a l'intention. Si j'utilise votre code et d'utiliser le "mode Débogage Hiérarchie" de l'outil dans Xcode 6 la fenêtre principale est d'avis, dans le paysage, tandis que la nouvelle fenêtre est toujours dans le portrait. Tout cela a un sens parce que nous avons converti en l'espace de coordonnées je ne comprends pas comment la fenêtre principale est de pouvoir ressembler à elle est en mode paysage. Apple doit être en train de faire quelque chose de différent.
Il ressemble à la configuration de la racine-vue-contrôleur ne fonctionne pas non plus. La fenêtre est toujours pas considérée comme une rotation afin que la vue du contrôleur de la vue à l'intérieur il n'est pas correctement dimensionné.
Cela semble vraiment bizarre. Et si vous déboguez sans le code ci-dessus, affiche-t-il ce que le paysage?
OriginalL'auteur runmad
Dans iOS 7 et les versions antérieures,
UIWindow
's système de coordonnées ne tourne pas. Dans iOS 8 il ne. Je suppose que le cadre fourni de[[UIScreen mainScreen] bounds]
ne tient pas compte de la rotation, ce qui pourrait provoquer des problèmes comme ce que vous voyez.Au lieu d'obtenir l'image à partir de
UIScreen
, vous pourriez saisir le cadre de l'appDelegate de la clé actuelle de la fenêtre.Cependant, il ne semble pas vous avez vraiment besoin de fonctionnalités fournies par les
UIWindow
. Je voudrais faire écho à d'autres la recommandation de l'utilisation d'unUIView
à cette fin.UIView
est plus générique queUIWindow
, et doit être préféré.OriginalL'auteur Nick
La meilleure chose à faire est d'utiliser des points de vue au lieu de windows:
Mais si vous pensez que vous avez une raison valable de créer plus d'une fenêtre, je vous suggère de créer une sous-classe de
NSWindow
qui gère les tailles automatiquement.Notez également que windows utilise beaucoup de RAM, surtout sur 3x écrans retina. Ayant plus d'un d'entre eux va réduire la quantité de mémoire que le reste de votre application peut utiliser avant de recevoir les avertissements de mémoire faible et finit par être tué.
Pourquoi devrait
UIView
être préférable si unUIWindow
est-elle nécessaire? (Je demande à l'affiche de la réponse) Il y a plusieurs cas où l'on peut vouloir utiliser une deuxième ou une troisièmeUIWindow
, comme Reid points qu'il veut un à s'asseoir àUIWindowLevelStatusBar
. Aussi, l'ajout d'unUIView
comme une sous-vue de UIWindow n'est pas idéal lorsque l'on veut n'importe quel type de contrôle sur leUIStatusBarStyle
- ça va être vraiment salissant rapide à manipuler toute modification de la barre d'état.Abhi, vous pouvez poster votre source pour votre commentaire sur
UIWindow
'substantielle de l'utilisation de la mémoire?une fenêtre principal objectif est de stocker les pixels de l'être dessiné à l'écran. Sur Mac OS X, ils écrivent souvent ce mémoire vers le disque dur/SSD à réduire l'ensemble de la mémoire de chargement. Mais depuis iOS l'utilisation de dispositifs de mémoire flash NAND au lieu des disques HDD/SSD de la mémoire, et la mémoire NAND flash ne gère pas fréquentes écrit bien, iOS a garder toutes les fenêtres dans la mémoire vive tout le temps. Ce n'est pas documentée nulle part pour iOS, mais il est documenté pour OS X et si la charge de la mémoire est un problème sur un mac avec 12 go de mémoire, alors c'est encore pire sur iOS et c'est ma compréhension de pourquoi les applications iOS ont une fenêtre, et les Applications Mac, de nombreuses fenêtres.
Par exemple, l'OS X dock dispose d'une fenêtre distincte pour chaque icône de l'application. Mais pour l'iOS d'Apple est allé à l'étendue de longueurs d'améliorer le système de vue d'éliminer la nécessité d'avoir plus qu'une fenêtre. La seule raison logique de le faire, qui je pense, est de réduire l'utilisation de la RAM.
OriginalL'auteur Abhi Beckert