C objectif : Obtenir la hauteur et la largeur d'une UIView avec précision
Je avoir des problèmes pour obtenir une lecture précise de la hauteur et la largeur. J'ai donc fait cette rapide et sale app pour tester la situation.
Voici le code:
@interface wwfpViewController ()
@property (nonatomic, strong) UIView * box;
@property (nonatomic, strong) UILabel * info;
@end
@implementation wwfpViewController
@synthesize box,info;
- (void)viewDidLoad {
[super viewDidLoad];
box=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[box setBackgroundColor:[UIColor darkGrayColor]];
[box setAutoresizesSubviews:YES];
[box setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
info=[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 300)];
[info setTextColor:[UIColor whiteColor]];
[info setBackgroundColor:[UIColor blackColor]];
[info setLineBreakMode:NSLineBreakByWordWrapping];
[info setNumberOfLines:10];
[info setText:@"..."];
[self.view addSubview:box];
[box addSubview:info];
[self updateInfo];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateView:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
}
- (void) updateInfo {
CGFloat selfHeight=self.view.frame.size.height;
CGFloat selfWidth=self.view.frame.size.width;
CGFloat boxHeight=box.frame.size.height;
CGFloat boxWidth=box.frame.size.width;
int deviceOrientation=[[UIDevice currentDevice] orientation];
int statusOrientation=[[UIApplication sharedApplication] statusBarOrientation];
NSString * str=[NSString stringWithFormat:@"[height x width] \nself: [%f x %f] \nbox: [%f x %f] \ndevice: %d status: %d",selfHeight,selfWidth,boxHeight,boxWidth,deviceOrientation,statusOrientation];
[info setText:str];
}
- (void) updateView: (NSNotification*) notify {
[self updateInfo];
}
@end
Quand je l'ai tester sur un iPad, d'abord en mode portrait, les informations d'étiquette indique ce qui suit:
[height x width]
self: [1004.000000 x 768.000000]
box: [1004.000000 x 768.000000]
device: 0 status: 1
C'est correct!
Et puis quand j'ai faites pivoter l'iPad en mode paysage, je reçois ces lectures:
[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Hauteur x largeur: 748 x 1024
Mais quand j'ai tester sur l'iPad lors de sa en orientation paysage, l'info de l'étiquette de rapports:
[height x width]
self: [1024.000000 x 748.000000]
box: [1024.000000 x 748.000000]
device: 0 status: 3
Hauteur x largeur: 748 x 1024
Puis quand j'ai faites pivoter l'iPad en mode portrait, je reçois ces lectures:
[height x width]
self: [748.000000 x 1024.000000]
box: [748.000000 x 1024.000000]
device: 1 status: 1
Hauteur x largeur: 1004 x 768
Je faire tourner le dos au paysage, puis-je obtenir ces lectures:
[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Hauteur x largeur: 748 x 1024
Dans tous les cas, le box
UIView couvre la totalité de l'écran, de sorte qu'il est auto réglage de l'orientation des changements correctement. Ces résultats sont cohérents à partir du simulateur et de le tester sur un iPad, et j'ai des expériences similaires sur un iPhone.
Après cela, j'ai quelques questions:
- Ce que je fais mal?
- Pourquoi la hauteur et de la largeur de
self.view
différente de la hauteur et de la largeur debox
lorsque les deux semblent visuellement identiques? -
Comment puis-je obtenir avec précision la hauteur et la largeur de l'écran ou affichage, indépendamment des changements d'orientation.
- Parce que
[UIDevice ... orientation]
rapports à zéro la première fois qu'il est utilisé, dois-je simplement l'ignorer complètement et simplement s'en tenir à[UIApplication ... statusBarOrientation]
?
NSLog(@"NSStringFromCGRect(@"%@",self.view.frame);
dansviewDidAppear:
méthode. pas dansviewDidLoad:
.- Et si vous voulez obtenir la taille de l'écran donc j'ai récemment donné une réponse here.
- mettre ce code dans
viewDidAppear:
ne fait aucune différence. - Vous devriez faire la mise en page dans le
viewWillLayoutSubview
méthode, pas dansviewDidLoad
. - Après l'apparition de l'affichage, il donne de la hauteur et la largeur de
self.view
n'est-ce pas ? Eh bien, j'en principe de calculer manuellement comme lien ci-dessus. - Mettre ce code dans
viewWillLayoutSubviews
encore les rapports de la hauteur et la largeur à tort. Veuillez donner mon code de l'essayer et voir par vous-même. - J'espérais être en mesure de simplement obtenir une lecture précise de la hauteur et la largeur, sans calculer manuellement. S'il vous plaît copiez et collez code ci-dessus dans Xcode et voir si vous obtenez des résultats similaires, il est très déroutant.
- Et ce que vous obtenez lorsque vous essayez de
viewDidAppear:
. En fait, je suis à la maison et ne t ont mac ne peut donc pas tester. Mais sûr que je vais l'essayer demain. - Est-ce que votre app/view controller effectivement prendre en charge toutes les orientations différentes (la vue contrôleur de rotation)? Ne pas utiliser la notification.
UIViewController
a beaucoup de méthodes que vous devez mettre en œuvre pour traiter avec les rotations. - Et aussi, ne pas utiliser d'un redimensionnement automatique plutôt la méthode de changement de la boîte de cadre dans
didRotateOrientation..
méthode pourbox.frame = self.bounds
. - Je soutiens toutes les différentes orientations. Veuillez donner mon code un aller et voir si vous obtenez les mêmes résultats étranges.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{NSLog(@"NSStringFromCGRect(@"%@",self.view.frame);};
Avez-vous essayé ? @JimmeryviewDidAppear:
fait la différence quand vous venez dans viewController en mode paysage.- stackoverflow.com/questions/18207038/...
- j'ai le même problème, j'ai utilisé le performselector après le délai de 0,3. il donne un parfait reasult.
- Vous étiez face à problème avec
window
taille ouself.view
taille ? - Tigre de soi.vue la taille
Vous devez vous connecter pour publier un commentaire.
Vérifier les limites des points de vue plutôt que de l'image:
Aussi, je voudrais utiliser le
UIViewController
méthode pour les changements d'orientation et de supprimer lesNSNotificationCenter
observateur.Enfin, le premier appel pour obtenir la taille correcte devrait être dans
viewWillAppear
comme il va être incorrecte dansviewDidLoad
:J'ai essayé votre code et trouvé qu'une seule erreur ici.
Cause de bug- Vous n'avez pas fait application
navigationController
basée àappdelegate
. Définissez votrewindow
'srootViewController
ànavigationController
ne sais pas pourquoi maisviewController
's en fonction de la vue ne donne pas le bon cadre.Mon Avis- Ne pas utiliser
notification
ici lorsque vous avez déjà une méthode-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
qui est appel après avoir changé d'orientation. Bien que Vous utiliseznotification
alors NP c'est juste mon avis.Une chose que je voudrais dire
Pourquoi ne pas simplement faire
Votre Code est correct. Il suffit de régler votre fenêtre rootViewController à navigationController OU tabbarController.
C'est Exemple De Code.
-didRotateFromInterfaceOrientation
me donne encore des lectures erronées lorsque l'iPad est le paysage.viewDidAppear:
effets comme tu disais qui n'a pas de sens.D'Apple docs
Il a probablement à voir avec
autoresizing masks
lire plus à ce sujet ici.De travail pour moi
J'ai fait des macros
vWidth
etvHeight
qui gérera l'ensemble de cette logique correctement, avec des issues: