2011-09-01 2 views
0

Je veux faire pivoter mon UIView "containerView" (boîte rouge semi-transparente dans la capture d'écran) en utilisant UIDeviceOrientationDidChangeNotification et plus tard (après qu'il tourne) ajouter des sous-couches à la couche de la vue, mais Je trouve que seules les limites de containerView.layer sont redimensionnées, et PAS le cadre de containerView.layer! :(Rotation de UIView y compris les bornes CALayer ET le cadre CALayer

Voilà comment il regarde en mode portrait:

portrait

Exemple Code:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    CALayer *r = [CALayer layer]; 
    r.frame = CGRectMake(0, 0, 100, 100); 
    r.contents = (id)[[UIImage imageNamed:@"r.png"] CGImage]; 
    [self.containerView.layer addSublayer:r]; 
} 

- (void)deviceRotated:(NSNotification *)notification 
{ 
    ... 
    if (orientation == UIDeviceOrientationLandscapeLeft) { 
     self.containerView.transform = CGAffineTransformMakeRotation(RADIANS(90)); 
     self.containerView.bounds = CGRectMake(0, 0, 411.0, 320.0); 

     NSLog(@"container bounds: %@", NSStringFromCGRect(self.containerView.bounds)); 
     NSLog(@"container layer frame: %@", NSStringFromCGRect(self.containerView.layer.frame)); 
     NSLog(@"container layer bounds: %@", NSStringFromCGRect(self.containerView.layer.bounds)); 

     CALayer *testLayer = [CALayer layer]; 
     testLayer.backgroundColor = [[UIColor blueColor] CGColor]; 
     testLayer.bounds = self.containerView.layer.frame; 
     testLayer.position = CGPointMake(CGRectGetMidX(testLayer.bounds), CGRectGetMidY(testLayer.bounds)); 
     [self.containerView.layer addSublayer:testLayer]; 
    } 
} 

qui, après rotation, impressions:

container bounds: {{0, 0}, {411, 320}} 
container layer frame: {{0, 0}, {320, 411}} 
container layer bounds: {{0, 0}, {411, 320}} 

(Notez de la couche le cadre est toujours large de 320, 411 haut.)

Alors maintenant, il ressemble à:

landscape left

J'ai essayé également de mettre au centre avant de changer les limites, mais qui ressemble à:

landscape left with setting center

Je sais que la couche du containerView doesn 't autoresize, donc j'ai essayé de définir le cadre de la couche après la transformation ... self.containerView.layer.frame = self.containerView.bounds; qui imprime ensuite:

container bounds: {{0, 0}, {320, 411}} 
container layer frame: {{0, 0}, {411, 320}} 
container layer bounds: {{0, 0}, {320, 411}} 

et ressemble à:

landscape left and setting layer frame

Argh! Le paramètre autoResizesSubviews est défini sur YES pour toutes les vues, clipsToBounds sur NO. Je ne peux pas utiliser shouldAutorotateToInterfaceOrientation parce que l'application réelle aura un aperçu de la caméra, donc je veux que la vue racine reste en mode portrait.

Il me manque quelque chose avec la façon dont je fais la transformation sur containerView pour que les limites et le cadre de la couche soient les mêmes, mais je n'arrive pas à comprendre ce que c'est! Toute aide serait très appréciée.

Mise à jour - Correction:

Réglage de la limite de la couche de nouveau ajoutée (testLayer.bounds) à contentView.layer.bounds au lieu de contentView.layer.frame a fait l'affaire. (Depuis la transformation de contentView invalide son layer.frame.) Merci Michael!

fixe:

contentView.layer.bounds instead of contentView.layer.frame

+0

Avant de publier une réponse, avez-vous essayé de retourner les valeurs dans self.containerView.bounds = CGRectMake (0, 0, 411.0, 320.0); – Kaiser

+0

Merci pour la suggestion! J'ai essayé cela et il semble que c'est presque là: http://f.cl.ly/items/371I0q1O3O0e0E3A0O0P/r_land_bounds_320_411.png - Bien que la trame de la couche conteneur soit {{-45.5, 45.5}, ​​{411, 320} et la Les limites de la couche sont: {{0, 0}, {320, 411}} – taber

+0

Les valeurs des trames ne sont pas utiles lorsqu'une vue a été transformée. From apple doc Avertissement: Si la propriété transform n'est pas la transformation d'identité, la valeur de cette propriété (frame) est indéfinie et doit donc être ignorée. – Kaiser

Répondre

2
self.containerView.bounds = CGRectMake(0, 0, 411.0, 320.0); 

Votre réglage ici est mauvais en raison du contexte renversé. Vous l'avez défini comme étant large et parce qu'il est retourné à 90 degrés, il redevient vertical.

+0

Merci, la seule chose est que maintenant les limites de containerView semblent toujours être 320 x 411. Et si je les force à 411 x 320 je suis de retour à la case départ avec le cadre de couche revenant à 320 x 411. :( – taber

+0

VICTORY Comme après la transformation, le cadre de containerView.layer est indéfini/ignoré, j'ai changé la ligne 'testLayer.bounds = self.containerView.layer.frame;' en 'testLayer.bounds = self.containerView.layer.bounds;' et cela a fonctionné http://f.cl.ly/items/2k042r3p1e1g3N0H010C/r_land_bounds.png - merci beaucoup! – taber

+0

Pas de problème content que je puisse aider, et oui à chaque fois qu'une transformation se produit la propriété frame devient garbage – Kaiser